home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / cc / g++-dist / cplus-parse.y < prev    next >
Encoding:
Text File  |  1990-03-09  |  88.6 KB  |  3,175 lines

  1. /* YACC parser for C++ syntax.
  2.    Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  3.    Hacked by Michael Tiemann (tiemann@mcc.com)
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. /* This grammar is based on the GNU CC grammar.  */
  23.  
  24. /* Also note: this version contains experimental exception
  25.    handling features.  They could break, change, disappear,
  26.    or otherwise exhibit volatile behavior.  Don't depend on
  27.    me (Michael Tiemann) to protect you from any negative impact
  28.    this may have on your professional, personal, or spiritual life.  */
  29.  
  30. %{
  31. #include "config.h"
  32. #include "tree.h"
  33. #include "input.h"
  34. #include "cplus-parse.h"
  35. #include "cplus-tree.h"
  36. #include "assert.h"
  37.  
  38. /* C++ extensions */
  39. extern tree ridpointers[];    /* need this up here */
  40. extern tree void_list_node;
  41.  
  42. #include <stdio.h>
  43. #include <errno.h>
  44.  
  45. #ifndef errno
  46. extern int errno;
  47. #endif
  48.  
  49. extern int end_of_file;
  50.  
  51. void yyerror ();
  52.  
  53. /* Contains error message to give if user tries to declare
  54.    a variable where one does not belong.  */
  55. static char *stmt_decl_msg = 0;
  56.  
  57. #ifndef YYDEBUG
  58. /* Cause the `yydebug' variable to be defined.  */
  59. int yydebug;
  60. #endif
  61.  
  62. /* Cons up an empty parameter list.  */
  63. #ifdef __GNU__
  64. __inline
  65. #endif
  66. static tree
  67. empty_parms ()
  68. {
  69.   tree parms;
  70.  
  71.   if (strict_prototype)
  72.     parms = void_list_node;
  73.   else
  74.     parms = NULL_TREE;
  75.   return parms;
  76. }
  77.  
  78. void yyhook ();
  79. %}
  80.  
  81. %start program
  82.  
  83. %union {long itype; tree ttype; enum tree_code code; }
  84.  
  85. /* All identifiers that are not reserved words
  86.    and are not declared typedefs in the current block */
  87. %token IDENTIFIER
  88.  
  89. /* All identifiers that are declared typedefs in the current block.
  90.    In some contexts, they are treated just like IDENTIFIER,
  91.    but they can also serve as typespecs in declarations.  */
  92. %token TYPENAME
  93.  
  94. /* Reserved words that specify storage class.
  95.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  96. %token SCSPEC
  97.  
  98. /* Reserved words that specify type.
  99.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  100. %token TYPESPEC
  101.  
  102. /* Reserved words that qualify type: "const" or "volatile".
  103.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  104. %token TYPE_QUAL
  105.  
  106. /* Character or numeric constants.
  107.    yylval is the node for the constant.  */
  108. %token CONSTANT
  109.  
  110. /* String constants in raw form.
  111.    yylval is a STRING_CST node.  */
  112. %token STRING
  113.  
  114. /* "...", used for functions with variable arglists.  */
  115. %token ELLIPSIS
  116.  
  117. /* the reserved words */
  118. %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  119. %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF
  120. %token ATTRIBUTE
  121.  
  122. /* the reserved words... C++ extensions */
  123. %token <ttype> AGGR
  124. %token DELETE NEW OVERLOAD PRIVATE PUBLIC PROTECTED THIS OPERATOR
  125. %token DYNAMIC POINTSAT_LEFT_RIGHT LEFT_RIGHT
  126. %token <itype> SCOPE
  127.  
  128. /* Define the operator tokens and their precedences.
  129.    The value is an integer because, if used, it is the tree code
  130.    to use in the expression made from the operator.  */
  131.  
  132. %left EMPTY            /* used to resolve s/r with epsilon */
  133.  
  134. /* Add precedence rules to solve dangling else s/r conflict */
  135. %nonassoc IF
  136. %nonassoc ELSE
  137.  
  138. %left IDENTIFIER TYPENAME TYPENAME_COLON SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR
  139.  
  140. %left '{' ','
  141.  
  142. %right <code> ASSIGN '='
  143. %right <code> '?' ':' RANGE
  144. %left <code> OROR
  145. %left <code> ANDAND
  146. %left <code> '|'
  147. %left <code> '^'
  148. %left <code> '&'
  149. %left <code> MIN_MAX
  150. %left <code> EQCOMPARE
  151. %left <code> ARITHCOMPARE
  152. %left <code> LSHIFT RSHIFT
  153. %left <code> '+' '-'
  154. %left <code> '*' '/' '%'
  155. %right <code> UNARY PLUSPLUS MINUSMINUS
  156. %left HYPERUNARY
  157. %left <ttype> PAREN_STAR_PAREN PAREN_X_SCOPE_STAR_PAREN PAREN_X_SCOPE_REF_PAREN LEFT_RIGHT
  158. %left <code> POINTSAT '.' '(' '['
  159.  
  160. %right SCOPE            /* C++ extension */
  161. %nonassoc NEW DELETE RAISE RAISES RERAISE TRY EXCEPT CATCH
  162. %right DYNAMIC
  163.  
  164. %type <code> unop
  165.  
  166. %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
  167. %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
  168. %type <ttype> typed_declspecs reserved_declspecs
  169. %type <ttype> typed_typespecs reserved_typespecquals
  170. %type <ttype> declmods typespec typespecqual_reserved
  171. %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
  172. %type <itype> initdecls notype_initdecls initdcl    /* C++ modification */
  173. %type <ttype> init initlist maybeasm
  174. %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
  175. %type <ttype> maybe_attribute attribute_list attrib
  176.  
  177. %type <ttype> compstmt except_stmts
  178.  
  179. %type <ttype> declarator notype_declarator after_type_declarator
  180.  
  181. %type <ttype> structsp opt.component_decl_list component_decl_list component_decl components component_declarator
  182. %type <ttype> enumlist enumerator
  183. %type <ttype> typename absdcl absdcl1 type_quals
  184. %type <ttype> xexpr see_typename parmlist parms parm bad_parm
  185.  
  186. /* C++ extensions */
  187. %token <ttype> TYPENAME_COLON TYPENAME_SCOPE TYPENAME_ELLIPSIS
  188. %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
  189. %type <ttype> fn.def2 dummy_decl x_typespec return_id
  190. %type <ttype> class_head opt.init base_class_list base_class_visibility_list
  191. %type <ttype> after_type_declarator_no_typename
  192. %type <ttype> maybe_raises raise_identifier raise_identifiers
  193. %type <ttype> component_declarator0 scoped_identifier
  194. %type <ttype> forhead.1 identifier_or_opname operator_name
  195. %type <ttype> new delete object primary_no_id aggr nonmomentary_expr
  196. %type <itype> LC forhead.2 initdcl0 notype_initdcl0 wrapper member_init_list
  197. %type <itype> try
  198.  
  199. %{
  200. /* the declaration found for the last IDENTIFIER token read in.
  201.    yylex must look this up to detect typedefs, which get token type TYPENAME,
  202.    so it is left around in case the identifier is not a typedef but is
  203.    used in a context which makes it a reference to a variable.  */
  204. tree lastiddecl;
  205.  
  206. tree make_pointer_declarator (), make_reference_declarator ();
  207.  
  208. tree combine_strings ();
  209. void reinit_parse_for_function ();
  210. void reinit_parse_for_method ();
  211.  
  212. /* List of types and structure classes of the current declaration.  */
  213. tree current_declspecs;
  214.  
  215. int undeclared_variable_notice;    /* 1 if we explained undeclared var errors.  */
  216.  
  217. int yylex ();
  218. extern FILE *finput;
  219. %}
  220.  
  221. %%
  222. program: /* empty */
  223.     | extdefs
  224.         { finish_file (); }
  225.     ;
  226.  
  227. /* the reason for the strange actions in this rule
  228.  is so that notype_initdecls when reached via datadef
  229.  can find a valid list of type and sc specs in $0. */
  230.  
  231. extdefs:
  232.       {$<ttype>$ = NULL_TREE; } extdef
  233.     | extdefs {$<ttype>$ = NULL_TREE; } extdef
  234.     ;
  235.  
  236. extdef:
  237.       fndef
  238.         { if (pending_inlines) do_pending_inlines (); }
  239.     | datadef
  240.         { if (pending_inlines) do_pending_inlines (); }
  241.     | overloaddef
  242.     | ASM '(' string ')' ';'
  243.         { if (pedantic)
  244.             warning ("ANSI C forbids use of `asm' keyword");
  245.           if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  246.           assemble_asm ($3); }
  247.     | extern_lang_string '{' extdefs '}'
  248.         { pop_lang_context (); }
  249.     | extern_lang_string '{' '}'
  250.         { pop_lang_context (); }
  251.     | extern_lang_string fndef
  252.         { if (pending_inlines) do_pending_inlines ();
  253.           pop_lang_context (); }
  254.     | extern_lang_string datadef
  255.         { if (pending_inlines) do_pending_inlines ();
  256.           pop_lang_context (); }
  257.     ;
  258.  
  259. extern_lang_string:
  260.       EXTERN_LANG_STRING
  261.         { push_lang_context ($1); }
  262.     ;
  263.  
  264. overloaddef:
  265.       OVERLOAD ov_identifiers ';'
  266.  
  267. ov_identifiers: IDENTIFIER
  268.         { declare_overloaded ($1); }
  269.     | ov_identifiers ',' IDENTIFIER
  270.         { declare_overloaded ($3); }
  271.     ;
  272.       
  273. dummy_decl: /* empty */
  274.         { $$ = NULL_TREE; }
  275.     ;
  276.  
  277. datadef:
  278.       dummy_decl notype_initdecls ';'
  279.         { if (pedantic)
  280.             error ("ANSI C forbids data definition lacking type or storage class");
  281.             else if (! flag_traditional)
  282.               warning ("data definition lacks type or storage class"); }
  283.     | declmods notype_initdecls ';'
  284.         {}
  285.     /* Normal case to make fast: "int i;".  */
  286.     | declmods declarator ';'
  287.         { tree d;
  288.           d = start_decl ($2, $1, 0, NULL_TREE);
  289.           finish_decl (d, NULL_TREE, NULL_TREE);
  290.         }
  291.     | typed_declspecs initdecls ';'
  292.         {
  293.           end_exception_decls ();
  294.           note_got_semicolon ($1);
  295.         }
  296.     /* Normal case: make this fast.  */
  297.     | typed_declspecs declarator ';'
  298.         { tree d;
  299.           d = start_decl ($2, $1, 0, NULL_TREE);
  300.           finish_decl (d, NULL_TREE, NULL_TREE);
  301.           end_exception_decls ();
  302.           note_got_semicolon ($1);
  303.         }
  304.         | declmods ';'
  305.       { error ("empty declaration"); }
  306.     | typed_declspecs ';'
  307.       {
  308.         shadow_tag ($1);
  309.         note_got_semicolon ($1);
  310.       }
  311.     | error ';'
  312.     | error '}'
  313.     | ';'
  314.     ;
  315.  
  316. fndef:
  317.       fn.def1 base_init compstmt_or_error
  318.         {
  319.           finish_function (lineno, 1);
  320.           /* finish_function performs these three statements:
  321.  
  322.              expand_end_bindings (getdecls (), 1, 0);
  323.              poplevel (1, 1, 0);
  324.  
  325.              expand_end_bindings (0, 0, 0);
  326.              poplevel (0, 0, 1);
  327.              */
  328.         }
  329.     | fn.def1 return_init base_init compstmt_or_error
  330.         {
  331.           finish_function (lineno, 1);
  332.           /* finish_function performs these three statements:
  333.  
  334.              expand_end_bindings (getdecls (), 1, 0);
  335.              poplevel (1, 1, 0);
  336.  
  337.              expand_end_bindings (0, 0, 0);
  338.              poplevel (0, 0, 1);
  339.              */
  340.         }
  341.     | fn.def1 nodecls compstmt_or_error
  342.         { finish_function (lineno, 0); }
  343.     | fn.def1 return_init ';' nodecls compstmt_or_error
  344.         { finish_function (lineno, 0); }
  345.     | fn.def1 return_init nodecls compstmt_or_error
  346.         { finish_function (lineno, 0); }
  347.     | typed_declspecs declarator error
  348.         {}
  349.     | declmods notype_declarator error
  350.         {}
  351.     | dummy_decl notype_declarator error
  352.         {}
  353.     ;
  354.  
  355. fn.def1:
  356.       typed_declspecs declarator maybe_raises
  357.         { if (! start_function ($1, $2, $3, 0))
  358.             YYERROR;
  359.           reinit_parse_for_function (); }
  360.     | declmods notype_declarator maybe_raises
  361.         { if (! start_function ($1, $2, $3, 0))
  362.             YYERROR;
  363.           reinit_parse_for_function (); }
  364.     | dummy_decl notype_declarator maybe_raises
  365.         { if (! start_function (NULL_TREE, $2, $3, 0))
  366.             YYERROR;
  367.           reinit_parse_for_function (); }
  368.     | dummy_decl TYPENAME '(' parmlist ')' type_quals maybe_raises
  369.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $2, $4, $6), $7, 0))
  370.             YYERROR;
  371.           reinit_parse_for_function (); }
  372.     | dummy_decl TYPENAME LEFT_RIGHT type_quals maybe_raises
  373.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $2, empty_parms (), $4), $5, 0))
  374.             YYERROR;
  375.           reinit_parse_for_function (); }
  376.     | PRE_PARSED_FUNCTION_DECL
  377.         { start_function (NULL_TREE, $1, NULL_TREE, 1);
  378.           reinit_parse_for_function (); }
  379.     ;
  380.  
  381. /* more C++ complexity */
  382. fn.def2:
  383.       typed_declspecs '(' parmlist ')' type_quals maybe_raises
  384.         {
  385.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
  386.           $$ = start_method (TREE_CHAIN ($1), decl, $6);
  387.           if (! $$)
  388.             YYERROR;
  389.           if (yychar == YYEMPTY)
  390.             yychar = YYLEX;
  391.           reinit_parse_for_method (yychar, $$); }
  392.     | typed_declspecs LEFT_RIGHT type_quals maybe_raises
  393.         {
  394.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), empty_parms (), $3);
  395.           $$ = start_method (TREE_CHAIN ($1), decl, $4);
  396.           if (! $$)
  397.             YYERROR;
  398.           if (yychar == YYEMPTY)
  399.             yychar = YYLEX;
  400.           reinit_parse_for_method (yychar, $$); }
  401.     | typed_declspecs declarator maybe_raises
  402.         { $$ = start_method ($1, $2, $3);
  403.           if (! $$)
  404.             YYERROR;
  405.           if (yychar == YYEMPTY)
  406.             yychar = YYLEX;
  407.           reinit_parse_for_method (yychar, $$); }
  408.     | declmods '(' parmlist ')' type_quals maybe_raises
  409.         {
  410.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
  411.           $$ = start_method (TREE_CHAIN ($1), decl, $6);
  412.           if (! $$)
  413.             YYERROR;
  414.           if (yychar == YYEMPTY)
  415.             yychar = YYLEX;
  416.           reinit_parse_for_method (yychar, $$); }
  417.     | declmods LEFT_RIGHT type_quals maybe_raises
  418.         {
  419.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($1), empty_parms (), $3);
  420.           $$ = start_method (TREE_CHAIN ($1), decl, $4);
  421.           if (! $$)
  422.             YYERROR;
  423.           if (yychar == YYEMPTY)
  424.             yychar = YYLEX;
  425.           reinit_parse_for_method (yychar, $$); }
  426.     | declmods declarator maybe_raises
  427.         { $$ = start_method ($1, $2, $3);
  428.           if (! $$)
  429.             YYERROR;
  430.           if (yychar == YYEMPTY)
  431.             yychar = YYLEX;
  432.           reinit_parse_for_method (yychar, $$); }
  433.     | dummy_decl notype_declarator maybe_raises
  434.         { $$ = start_method (NULL_TREE, $2, $3);
  435.           if (! $$)
  436.             YYERROR;
  437.           if (yychar == YYEMPTY)
  438.             yychar = YYLEX;
  439.           reinit_parse_for_method (yychar, $$); }
  440.     ;
  441.  
  442. return_id: RETURN IDENTIFIER
  443.         {
  444.           if (! current_function_parms_stored)
  445.             store_parm_decls ();
  446.           $$ = $2;
  447.         }
  448.     ;
  449.  
  450. return_init: return_id opt.init
  451.         {
  452.           extern tree value_identifier;
  453.           tree result;
  454.  
  455.           result = DECL_RESULT (current_function_decl);
  456.           if (DECL_NAME (result) == value_identifier)
  457.             DECL_NAME (result) = $1;
  458.           else
  459.             error ("return identifier `%s' already in place",
  460.                IDENTIFIER_POINTER (DECL_NAME (result)));
  461.           store_return_init ($2);
  462.         }
  463.     | return_id '(' exprlist ')'
  464.         {
  465.           extern tree value_identifier;
  466.           tree result;
  467.  
  468.           result = DECL_RESULT (current_function_decl);
  469.           if (DECL_NAME (result) == value_identifier)
  470.             DECL_NAME (result) = $1;
  471.           else
  472.             error ("return identifier `%s' already in place",
  473.                IDENTIFIER_POINTER (DECL_NAME (result)));
  474.           store_return_init ($3);
  475.         }
  476.     | return_id LEFT_RIGHT
  477.         {
  478.           extern tree value_identifier;
  479.           tree result;
  480.  
  481.           result = DECL_RESULT (current_function_decl);
  482.           if (DECL_NAME (result) == value_identifier)
  483.             DECL_NAME (result) = $1;
  484.           else
  485.             error ("return identifier `%s' already in place",
  486.                IDENTIFIER_POINTER (DECL_NAME (result)));
  487.           store_return_init (NULL_TREE);
  488.         }
  489.     ;
  490.  
  491. base_init:
  492.       ':' .set_base_init member_init_list
  493.         { if ($3 == 0)
  494.             error ("no base initializers given following ':'");
  495.           setup_vtbl_ptr (); }
  496.     ;
  497.  
  498. .set_base_init:
  499.     /* empty */
  500.         {
  501.           int preserve = (current_class_type
  502.                   && TYPE_USES_VIRTUAL_BASECLASSES (current_class_type));
  503.           preserve = 0;    /* "in charge" arg means we no longer
  504.                    need this hack.  */
  505.           if (! current_function_parms_stored)
  506.             store_parm_decls ();
  507.           else if (preserve)
  508.             preserve_data ();
  509.  
  510.           /* Flag that we are processing base and member initializers.  */
  511.           current_vtable_decl = error_mark_node;
  512.  
  513.           if (DECL_CONSTRUCTOR_P (current_function_decl))
  514.             {
  515.               /* Make a contour for the initializer list.  */
  516.               pushlevel (0);
  517.               clear_last_expr ();
  518.               expand_start_bindings (0);
  519.             }
  520.           else if (current_class_type == NULL_TREE)
  521.             error ("base initializers not allowed for non-member functions");
  522.           else if (! DECL_CONSTRUCTOR_P (current_function_decl))
  523.             error ("only constructors take base initializers");
  524.         }
  525.     ;
  526.  
  527. member_init_list:
  528.       /* empty */
  529.         { $$ = 0; }
  530.     | member_init
  531.         { $$ = 1; }
  532.     | member_init_list ',' member_init
  533.     | member_init_list error
  534.     ;
  535.  
  536.  
  537.  
  538. member_init: '(' exprlist ')'
  539.         {
  540.           if (current_class_name && pedantic)
  541.             warning ("old style base class initialization; use `%s (...)'",
  542.                  IDENTIFIER_POINTER (current_class_name));
  543.           expand_member_init (C_C_D, NULL_TREE, $2);
  544.         }
  545.     | LEFT_RIGHT
  546.         {
  547.           if (current_class_name && pedantic)
  548.             warning ("old style base class initialization; use `%s (...)'",
  549.                  IDENTIFIER_POINTER (current_class_name));
  550.           expand_member_init (C_C_D, NULL_TREE, void_type_node);
  551.         }
  552.     | identifier '(' exprlist ')'
  553.         {
  554.           expand_member_init (C_C_D, $1, $3);
  555.         }
  556.     | identifier LEFT_RIGHT
  557.         { expand_member_init (C_C_D, $1, void_type_node); }
  558.     | scoped_identifier identifier '(' exprlist ')'
  559.         {
  560.           tree base, basetype;
  561.           tree scopes = $1;
  562.  
  563.           if (TREE_CODE (scopes) == SCOPE_REF)
  564.             /* just a pain to do this right now.  */
  565.             abort ();
  566.  
  567.           if (current_class_type == NULL_TREE
  568.               || ! is_aggr_typedef (scopes, 1))
  569.             break;
  570.           basetype = get_base_type (TREE_TYPE (TREE_TYPE (scopes)),
  571.                         current_class_type, 1);
  572.           if (basetype == error_mark_node)
  573.             break;
  574.           if (basetype == 0)
  575.             {
  576.               error_not_base_type (TREE_TYPE (TREE_TYPE (scopes)), current_class_type);
  577.               break;
  578.             }
  579.  
  580.           base = convert_pointer_to (basetype, current_class_decl);
  581.           expand_member_init (build_indirect_ref (base), $2, $4);
  582.         }
  583.     | scoped_identifier identifier LEFT_RIGHT
  584.         {
  585.           tree basetype, base;
  586.           tree scopes = $1;
  587.           if (TREE_CODE (scopes) == SCOPE_REF)
  588.             /* just a pain to do this right now.  */
  589.             abort ();
  590.  
  591.           if (current_class_type == NULL_TREE
  592.               || ! is_aggr_typedef (scopes, 1))
  593.             break;
  594.           basetype = get_base_type (TREE_TYPE (TREE_TYPE (scopes)),
  595.                         current_class_type, 1);
  596.           if (basetype == error_mark_node)
  597.             break;
  598.           if (basetype == 0)
  599.             {
  600.               error_not_base_type (TREE_TYPE (TREE_TYPE (scopes)), current_class_type);
  601.               break;
  602.             }
  603.  
  604.           base = convert_pointer_to (basetype, current_class_decl);
  605.           expand_member_init (build_indirect_ref (base), $2, void_type_node);
  606.         }
  607.     ;
  608.  
  609. identifier:
  610.       IDENTIFIER
  611.     | TYPENAME
  612.     ;
  613.  
  614. identifier_or_opname:
  615.       IDENTIFIER
  616.     | TYPENAME
  617.     | '~' identifier
  618.         { $$ = build_parse_node (BIT_NOT_EXPR, $2); }
  619.     | operator_name
  620.         { $$ = hack_operator ($1);
  621.           if ($$ == error_mark_node)
  622.             $$ = get_identifier ("<missing operator>"); }
  623.     | wrapper IDENTIFIER
  624.         { $$ = hack_wrapper ($1, NULL_TREE, $2); }
  625.     | wrapper TYPENAME
  626.         { $$ = hack_wrapper ($1, NULL_TREE, $2); }
  627.     | wrapper operator_name
  628.         { $$ = hack_wrapper ($1, NULL_TREE, $2); }
  629.     | wrapper scoped_identifier IDENTIFIER
  630.         { $$ = hack_wrapper ($1, $2, $3); }
  631.     | wrapper scoped_identifier operator_name
  632.         { $$ = hack_wrapper ($1, $2, $3); }
  633.     ;
  634.  
  635. wrapper:  LEFT_RIGHT
  636.         { $$ = 0; }
  637.     | '~' LEFT_RIGHT
  638.         { $$ = 1; }
  639.     | LEFT_RIGHT '?'
  640.         { $$ = 2; }
  641.     ;
  642.  
  643. unop:     '-'
  644.         { $$ = NEGATE_EXPR; }
  645.     | '+'
  646.         { $$ = CONVERT_EXPR; }
  647.     | PLUSPLUS
  648.         { $$ = PREINCREMENT_EXPR; }
  649.     | MINUSMINUS
  650.         { $$ = PREDECREMENT_EXPR; }
  651.     | '!'
  652.         { $$ = TRUTH_NOT_EXPR; }
  653.     ;
  654.  
  655. expr:      nonnull_exprlist
  656.         { $$ = build_compound_expr ($1); }
  657.     /* Ugly, but faster.  */
  658.     | expr_no_commas
  659.         {
  660.           if (TREE_CODE ($1) == CALL_EXPR
  661.               && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE ($1)))
  662.             $$ = cleanup_after_call ($1);
  663.         }
  664.     ;
  665.  
  666. exprlist:
  667.       /* empty */
  668.         { $$ = NULL_TREE; }
  669.     | nonnull_exprlist
  670.     ;
  671.  
  672. nonnull_exprlist:
  673.       expr_no_commas
  674.         { $$ = build_tree_list (NULL_TREE, $1); }
  675.     | nonnull_exprlist ',' expr_no_commas
  676.         { chainon ($1, build_tree_list (NULL_TREE, $3)); }
  677.     | nonnull_exprlist ',' error
  678.         { chainon ($1, build_tree_list (NULL_TREE, error_mark_node)); }
  679.     ;
  680.  
  681. unary_expr:
  682.       primary %prec UNARY
  683.         {
  684.           if (TREE_CODE ($1) == TYPE_EXPR)
  685.             $$ = build_component_type_expr (C_C_D, $1, NULL_TREE, 1);
  686.           else
  687.             $$ = $1;
  688.         }
  689.     | '*' cast_expr   %prec UNARY
  690.         { $$ = build_x_indirect_ref ($2, "unary *"); }
  691.     | '&' cast_expr   %prec UNARY
  692.         { $$ = build_x_unary_op (ADDR_EXPR, $2); }
  693.     | '~' cast_expr   %prec UNARY
  694.         { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); }
  695.     | unop cast_expr  %prec UNARY
  696.         { $$ = build_x_unary_op ($1, $2);
  697.           if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST)
  698.             TREE_NEGATED_INT ($$) = 1;
  699.         }
  700.     | SIZEOF unary_expr  %prec UNARY
  701.         { if (TREE_CODE ($2) == COMPONENT_REF
  702.               && TREE_PACKED (TREE_OPERAND ($2, 1)))
  703.             error ("sizeof applied to a bit-field");
  704.           /* ANSI says arrays and functions are converted inside comma.
  705.              But we can't really convert them in build_compound_expr
  706.              because that would break commas in lvalues.
  707.              So do the conversion here if operand was a comma.  */
  708.           if (TREE_CODE ($2) == COMPOUND_EXPR
  709.               && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
  710.               || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
  711.             $2 = default_conversion ($2);
  712.           $$ = c_sizeof (TREE_TYPE ($2)); }
  713.     | SIZEOF '(' typename ')'  %prec HYPERUNARY
  714.         { $$ = c_sizeof (groktypename ($3)); }
  715.     | ALIGNOF unary_expr  %prec UNARY
  716.         { if (TREE_CODE ($2) == COMPONENT_REF
  717.               && TREE_PACKED (TREE_OPERAND ($2, 1)))
  718.             error ("`__alignof' applied to a bit-field");
  719.           if (TREE_CODE ($2) == INDIRECT_REF)
  720.             {
  721.               tree t = TREE_OPERAND ($2, 0);
  722.               tree best = t;
  723.               int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
  724.               while (TREE_CODE (t) == NOP_EXPR
  725.                  && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
  726.             {
  727.               int thisalign;
  728.               t = TREE_OPERAND (t, 0);
  729.               thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
  730.               if (thisalign > bestalign)
  731.                 best = t, bestalign = thisalign;
  732.             }
  733.               $$ = c_alignof (TREE_TYPE (TREE_TYPE (best)));
  734.             }
  735.           else
  736.             {
  737.               /* ANSI says arrays and fns are converted inside comma.
  738.              But we can't convert them in build_compound_expr
  739.              because that would break commas in lvalues.
  740.              So do the conversion here if operand was a comma.  */
  741.               if (TREE_CODE ($2) == COMPOUND_EXPR
  742.               && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
  743.                   || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
  744.             $2 = default_conversion ($2);
  745.               $$ = c_alignof (TREE_TYPE ($2));
  746.             }
  747.         }
  748.     | ALIGNOF '(' typename ')'  %prec HYPERUNARY
  749.         { $$ = c_alignof (groktypename ($3)); }
  750.  
  751.     | new typename %prec '='
  752.         { $$ = build_new ($1, $2, NULL_TREE); }
  753.     | new x_typespec '(' exprlist ')'
  754.         { $$ = build_new ($1, $2, $4); }
  755.     | new x_typespec LEFT_RIGHT
  756.         { $$ = build_new ($1, $2, NULL_TREE); }
  757.     | new typename '=' init %prec '='
  758.         { $$ = build_new ($1, $2, $4); }
  759.     | new '(' typename ')'
  760.         { $$ = build_new ($1, $3, NULL_TREE); }
  761.     /* Unswallow a ':' which is probably meant for ?: expression.  */
  762.     | new TYPENAME_COLON
  763.         { yyungetc (':', 1);
  764.           $$ = build_new ($1, $2, NULL_TREE); }
  765.  
  766.     | delete cast_expr  %prec UNARY
  767.         { tree expr = convert_from_reference ($2);
  768.           tree type = TREE_TYPE (expr);
  769.  
  770.           if (integer_zerop (expr))
  771.             $$ = build1 (NOP_EXPR, void_type_node, expr);
  772.           else if (TREE_CODE (type) != POINTER_TYPE)
  773.             {
  774.               error ("non-pointer type to `delete'");
  775.               $$ = error_mark_node;
  776.             }
  777.           else if (! TYPE_LANG_SPECIFIC (TREE_TYPE (type))
  778.                || ! TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (type)))
  779.             $$ = build_delete (type, expr, integer_one_node,
  780.                        LOOKUP_NORMAL, $1);
  781.           else
  782.             {
  783.               $$ = build (COMPOUND_EXPR, void_type_node,
  784.                   build (COMPOUND_EXPR, void_type_node,
  785.                      build_delete (type, expr, integer_zero_node, LOOKUP_NORMAL, 0),
  786.                      build_vbase_delete (TREE_TYPE (type),
  787.                                  build_indirect_ref (expr))),
  788.                   build_x_delete (type, expr, $1));
  789.             }
  790.         }
  791.     | delete '[' expr ']' cast_expr  %prec UNARY
  792.         {
  793.           tree maxindex = build_binary_op (MINUS_EXPR, $3, integer_one_node);
  794.           tree exp = convert_from_reference ($5);
  795.           tree elt_size = c_sizeof (TREE_TYPE (exp));
  796.  
  797.           if (yychar == YYEMPTY)
  798.             yychar = YYLEX;
  799.  
  800.           $$ = build_vec_delete (exp, maxindex, elt_size, NULL_TREE,
  801.                      integer_one_node, integer_zero_node);
  802.         }
  803.     ;
  804.  
  805. cast_expr:
  806.       unary_expr
  807.     | '(' typename ')' expr_no_commas  %prec UNARY
  808.         { tree type = groktypename ($2);
  809.           $$ = build_c_cast (type, $4); }
  810.     | '(' typename ')' '{' initlist maybecomma '}'  %prec UNARY
  811.         { tree type = groktypename ($2);
  812.           tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5));
  813.           if (pedantic)
  814.             warning ("ANSI C forbids constructor-expressions");
  815.           /* Indicate that this was a GNU C constructor expression.  */
  816.           TREE_HAS_CONSTRUCTOR (init) = 1;
  817.           $$ = digest_init (type, init, 0);
  818.           if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
  819.             {
  820.               int failure = complete_array_type (type, $$, 1);
  821.               if (failure)
  822.             abort ();
  823.             }
  824.         }
  825.     ;
  826.  
  827. expr_no_commas:
  828.       cast_expr
  829.     | expr_no_commas '+' expr_no_commas
  830.         { $$ = build_x_binary_op ($2, $1, $3); }
  831.     | expr_no_commas '-' expr_no_commas
  832.         { $$ = build_x_binary_op ($2, $1, $3); }
  833.     | expr_no_commas '*' expr_no_commas
  834.         { $$ = build_x_binary_op ($2, $1, $3); }
  835.     | expr_no_commas '/' expr_no_commas
  836.         { $$ = build_x_binary_op ($2, $1, $3); }
  837.     | expr_no_commas '%' expr_no_commas
  838.         { $$ = build_x_binary_op ($2, $1, $3); }
  839.     | expr_no_commas LSHIFT expr_no_commas
  840.         { $$ = build_x_binary_op ($2, $1, $3); }
  841.     | expr_no_commas RSHIFT expr_no_commas
  842.         { $$ = build_x_binary_op ($2, $1, $3); }
  843.     | expr_no_commas ARITHCOMPARE expr_no_commas
  844.         { $$ = build_x_binary_op ($2, $1, $3); }
  845.     | expr_no_commas EQCOMPARE expr_no_commas
  846.         { $$ = build_x_binary_op ($2, $1, $3); }
  847.     | expr_no_commas MIN_MAX expr_no_commas
  848.         { $$ = build_x_binary_op ($2, $1, $3); }
  849.     | expr_no_commas '&' expr_no_commas
  850.         { $$ = build_x_binary_op ($2, $1, $3); }
  851.     | expr_no_commas '|' expr_no_commas
  852.         { $$ = build_x_binary_op ($2, $1, $3); }
  853.     | expr_no_commas '^' expr_no_commas
  854.         { $$ = build_x_binary_op ($2, $1, $3); }
  855.     | expr_no_commas ANDAND expr_no_commas
  856.         { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
  857.     | expr_no_commas OROR expr_no_commas
  858.         { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
  859.     | expr_no_commas '?' xexpr ':' expr_no_commas
  860.         { $$ = build_x_conditional_expr ($1, $3, $5); }
  861.     | expr_no_commas '=' expr_no_commas
  862.         { $$ = build_modify_expr ($1, NOP_EXPR, $3); }
  863.     | expr_no_commas ASSIGN expr_no_commas
  864.         { register tree rval;
  865.           if (rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $1, $3, $2))
  866.             $$ = rval;
  867.           else
  868.             $$ = build_modify_expr ($1, $2, $3); }
  869.  
  870.     /* Handle general members.  */
  871.     | object '*' expr_no_commas   %prec UNARY
  872.         { $$ = build_m_component_ref ($1, build_x_indirect_ref ($3, "unary *")); }
  873.     | object '&' expr_no_commas   %prec UNARY
  874.         { $$ = build_m_component_ref ($1, build_x_unary_op (ADDR_EXPR, $3)); }
  875.     | object unop expr_no_commas  %prec UNARY
  876.         { $$ = build_m_component_ref ($1, build_x_unary_op ($2, $3)); }
  877.     | object '(' typename ')' expr_no_commas  %prec UNARY
  878.         { tree type = groktypename ($3);
  879.           $$ = build_m_component_ref ($1, build_c_cast (type, $5)); }
  880.     | object primary_no_id  %prec UNARY
  881.         { $$ = build_m_component_ref ($1, $2); }
  882.     ;
  883.  
  884. primary:
  885.     IDENTIFIER
  886.         { $$ = lastiddecl;
  887.           if (yychar == YYEMPTY)
  888.             yychar = YYLEX;
  889.           /* Scope class declarations before global
  890.              declarations.  */
  891.           if ($$ == IDENTIFIER_GLOBAL_VALUE ($1)
  892.               && current_class_type != 0
  893.               && TYPE_SIZE (current_class_type) == 0)
  894.             {
  895.               /* Could be from one of the base classes.  */
  896.               tree field = lookup_field (current_class_type, $1, 1);
  897.               if (field == 0)
  898.             ;
  899.               else if (field == error_mark_node)
  900.             /* We have already generated the error message.
  901.                But we still want to return this value.  */
  902.             $$ = lookup_field (current_class_type, $1, 0);
  903.               else if (TREE_CODE (field) == VAR_DECL
  904.                    || TREE_CODE (field) == CONST_DECL)
  905.             $$ = field;
  906.               else if (TREE_CODE (field) != FIELD_DECL)
  907.             abort ();
  908.               else
  909.             {
  910.               error_with_decl (field, "invalid use of member `%s' from base class `%s'",
  911.                        TYPE_NAME_STRING (DECL_FIELD_CONTEXT (field)));
  912.               $$ = error_mark_node;
  913.               break;
  914.             }
  915.             }
  916.  
  917.           if (!$$ || $$ == error_mark_node)
  918.             {
  919.               if (yychar == '(' || yychar == LEFT_RIGHT)
  920.             {
  921.               $$ = implicitly_declare ($1);
  922.               assemble_external ($$);
  923.               TREE_USED ($$) = 1;
  924.             }
  925.               else if (current_function_decl == 0)
  926.             {
  927.               error ("`%s' undeclared, outside of functions",
  928.                  IDENTIFIER_POINTER ($1));
  929.               $$ = error_mark_node;
  930.             }
  931.               else
  932.             {
  933.               if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
  934.                   || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
  935.                 {
  936.                   error ("`%s' undeclared (first use this function)",
  937.                      IDENTIFIER_POINTER ($1));
  938.  
  939.                   if (! undeclared_variable_notice)
  940.                 {
  941.                   error ("(Each undeclared identifier is reported only once");
  942.                   error ("for each function it appears in.)");
  943.                   undeclared_variable_notice = 1;
  944.                 }
  945.                 }
  946.               $$ = error_mark_node;
  947.               /* Prevent repeated error messages.  */
  948.               IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
  949.               SET_IDENTIFIER_ERROR_LOCUS ($1, current_function_decl);
  950.             }
  951.             }
  952.           /* TREE_USED is set in `hack_identifier'.  */
  953.           if (TREE_CODE ($$) == CONST_DECL)
  954.             {
  955.               if (IDENTIFIER_CLASS_VALUE ($1) == $$)
  956.             {
  957.               /* Check visibility.  */
  958.               enum visibility_type visibility
  959.                 = compute_visibility (CLASSTYPE_AS_LIST (current_class_type), $$);
  960.               if (visibility == visibility_private)
  961.                 error_with_decl ($$, "enum `%s' is private");
  962.               /* protected is OK, since it's an enum of `this'.  */
  963.             }
  964.               $$ = DECL_INITIAL ($$);
  965.             }
  966.           else $$ = hack_identifier ($$, $1, yychar);
  967.         }
  968.     | operator_name
  969.         {
  970.           tree op = hack_operator ($1);
  971.           $$ = lookup_name (op);
  972.           if ($$ == NULL_TREE)
  973.             {
  974.               error ("operator %s not defined", operator_name_string (op));
  975.               $$ = error_mark_node;
  976.             }
  977.         }
  978.     | CONSTANT
  979.     | string
  980.         { $$ = combine_strings ($1); }
  981.     | '(' expr ')'
  982.         { $$ = $2; }
  983.     | '(' error ')'
  984.         { $$ = error_mark_node; }
  985.     | '('
  986.         { if (current_function_decl == 0)
  987.             {
  988.               error ("braced-group within expression allowed only inside a function");
  989.               YYERROR;
  990.             }
  991.           keep_next_level ();
  992.           $<ttype>$ = expand_start_stmt_expr (); }
  993.       compstmt ')'
  994.         { tree rtl_exp;
  995.           if (pedantic)
  996.             warning ("ANSI C forbids braced-groups within expressions");
  997.           rtl_exp = expand_end_stmt_expr ($<ttype>2);
  998.           $$ = $3;
  999.           TREE_USED ($$) = 0;
  1000.           /* Since the statements have side effects,
  1001.              consider this volatile.  */
  1002.           TREE_VOLATILE ($$) = 1;
  1003.           TREE_TYPE ($$) = TREE_TYPE (rtl_exp);
  1004.           STMT_BODY ($$) = rtl_exp; }
  1005.     | primary '(' exprlist ')'
  1006.         { $$ = build_x_function_call ($1, $3, current_class_decl); }
  1007.     | primary LEFT_RIGHT
  1008.         { $$ = build_x_function_call ($1, NULL_TREE, current_class_decl); }
  1009.     | primary '[' expr ']'
  1010.         {
  1011.         do_array:
  1012.           {
  1013.             tree type = TREE_TYPE ($1);
  1014.             if (type == error_mark_node || $3 == error_mark_node)
  1015.               $$ = error_mark_node;
  1016.             else if (type == NULL_TREE)
  1017.               {
  1018.             /* Something has gone very wrong.  Assume we
  1019.                are mistakenly reducing an expression
  1020.                instead of a declaration.  */
  1021.             error ("parser may be lost: is there a '{' missing somewhere?");
  1022.             $$ = NULL_TREE;
  1023.               }
  1024.             else
  1025.               {
  1026.             if (TREE_CODE (type) == OFFSET_TYPE)
  1027.               type = TREE_TYPE (type);
  1028.             if (TREE_CODE (type) == REFERENCE_TYPE)
  1029.               type = TREE_TYPE (type);
  1030.  
  1031.             if (TYPE_LANG_SPECIFIC (type) &&
  1032.                 TYPE_OVERLOADS_ARRAY_REF (type))
  1033.               $$ = build_opfncall (ARRAY_REF, LOOKUP_NORMAL, $1, $3);
  1034.             else if (TREE_CODE (type) == POINTER_TYPE
  1035.                  || TREE_CODE (type) == ARRAY_TYPE)
  1036.               $$ = build_array_ref ($1, $3);
  1037.             else
  1038.               error("[] applied to non-pointer type");
  1039.               }
  1040.           }
  1041.         }
  1042.     | object identifier_or_opname  %prec UNARY
  1043.         { $$ = build_component_ref ($1, $2, NULL_TREE, 1); }
  1044.     | object scoped_identifier identifier_or_opname %prec UNARY
  1045.         {
  1046.           tree basetype = (TREE_CODE ($2) == SCOPE_REF) ? TREE_OPERAND ($2, 1) : $2;
  1047.           if (is_aggr_typedef (basetype, 1))
  1048.             {
  1049.               basetype = TREE_TYPE (TREE_TYPE (basetype));
  1050.  
  1051.               if ($1 == error_mark_node)
  1052.             $$ = error_mark_node;
  1053.               else if (basetype_or_else (basetype, TREE_TYPE ($1)))
  1054.             $$ = build_component_ref (build_scoped_ref ($1, $2), $3, NULL_TREE, 1);
  1055.               else
  1056.             $$ = error_mark_node;
  1057.             }
  1058.           else $$ = error_mark_node;
  1059.         }
  1060.     | primary PLUSPLUS
  1061.         { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $1); }
  1062.     | primary MINUSMINUS
  1063.         { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $1); }
  1064.  
  1065.     /* C++ extensions */
  1066.     | THIS
  1067.         { if (current_class_decl)
  1068.             {
  1069. #ifdef WARNING_ABOUT_CCD
  1070.               TREE_USED (current_class_decl) = 1;
  1071. #endif
  1072.               $$ = current_class_decl;
  1073.             }
  1074.           else if (current_function_decl
  1075.                && DECL_STATIC_FUNCTION_P (current_function_decl))
  1076.             {
  1077.               error ("`this' is unavailable for static member functions");
  1078.               $$ = error_mark_node;
  1079.             }
  1080.           else
  1081.             {
  1082.               if (current_function_decl)
  1083.             error ("invalid use of `this' in non-member function");
  1084.               else
  1085.             error ("invalid use of `this' at top level");
  1086.               $$ = error_mark_node;
  1087.             }
  1088.         }
  1089.     | dummy_decl TYPE_QUAL '(' exprlist ')'
  1090.         {
  1091.           tree type;
  1092.           tree id = $2;
  1093.  
  1094.           /* This is a C cast in C++'s `functional' notation.  */
  1095.           if ($4 == error_mark_node)
  1096.             {
  1097.               $$ = error_mark_node;
  1098.               break;
  1099.             }
  1100. #if 0
  1101.           if ($4 == NULL_TREE)
  1102.             {
  1103.               error ("cannot cast null list to type `%s'",
  1104.                      IDENTIFIER_POINTER (TYPE_NAME ($2)));
  1105.               $$ = error_mark_node;
  1106.               break;
  1107.             }
  1108. #endif
  1109.           if (type == error_mark_node)
  1110.             $$ = error_mark_node;
  1111.           else
  1112.             {
  1113.               if (id == ridpointers[(int) RID_CONST])
  1114.                 type = build_type_variant (integer_type_node, 1, 0);
  1115.               else if (id == ridpointers[(int) RID_VOLATILE])
  1116.                 type = build_type_variant (integer_type_node, 0, 1);
  1117.               else if (id == ridpointers[(int) RID_FRIEND])
  1118.                 {
  1119.                   error ("cannot cast expression to `friend' type");
  1120.                   $$ = error_mark_node;
  1121.                   break;
  1122.                 }
  1123.               else abort ();
  1124.               $$ = build_c_cast (type, build_compound_expr ($4));
  1125.             }
  1126.         }
  1127.     | x_typespec '(' exprlist ')'
  1128.         { $$ = build_functional_cast ($1, $3); }
  1129.     | x_typespec LEFT_RIGHT
  1130.         { $$ = build_functional_cast ($1, NULL_TREE); }
  1131.     | SCOPE IDENTIFIER
  1132.         {
  1133.         do_scoped_identifier:
  1134.           $$ = IDENTIFIER_GLOBAL_VALUE ($2);
  1135.           if (yychar == YYEMPTY)
  1136.             yychar = YYLEX;
  1137.           if (! $$)
  1138.             {
  1139.               if (yychar == '(' || yychar == LEFT_RIGHT)
  1140.             {
  1141.               $$ = implicitly_declare ($2);
  1142.             }
  1143.               else
  1144.             {
  1145.               if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node)
  1146.                 error ("undeclared variable `%s' (first use here)",
  1147.                    IDENTIFIER_POINTER ($2));
  1148.               $$ = error_mark_node;
  1149.               /* Prevent repeated error messages.  */
  1150.               IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node;
  1151.             }
  1152.             }
  1153.           else if (TREE_CODE ($$) == CONST_DECL)
  1154.             $$ = DECL_INITIAL ($$);
  1155.           if (! TREE_USED ($$))
  1156.             {
  1157.               if (TREE_EXTERNAL ($$))
  1158.             assemble_external ($$);
  1159.               TREE_USED ($$) = 1;
  1160.             }
  1161.         }
  1162.     | SCOPE operator_name
  1163.         {
  1164.           $2 = hack_operator ($2);
  1165.           if (TREE_CODE ($2) == IDENTIFIER_NODE)
  1166.             goto do_scoped_identifier;
  1167.         do_scoped_operator:
  1168.           $$ = $2;
  1169.         }
  1170.     | scoped_identifier identifier_or_opname  %prec HYPERUNARY
  1171.         { $$ = build_offset_ref ($1, $2); }
  1172.     | scoped_identifier identifier_or_opname '(' exprlist ')'
  1173.         { $$ = build_member_call ($1, $2, $4); }
  1174.     | scoped_identifier identifier_or_opname LEFT_RIGHT
  1175.         { $$ = build_member_call ($1, $2, NULL_TREE); }
  1176.  
  1177.     | object identifier_or_opname '(' exprlist ')'
  1178.         { $$ = build_method_call ($1, $2, $4, NULL_TREE,
  1179.                       (LOOKUP_NORMAL|LOOKUP_AGGR)); }
  1180.     | object identifier_or_opname LEFT_RIGHT
  1181.         { $$ = build_method_call ($1, $2, NULL_TREE, NULL_TREE,
  1182.                       (LOOKUP_NORMAL|LOOKUP_AGGR)); }
  1183.     | object scoped_identifier identifier_or_opname '(' exprlist ')'
  1184.         { $$ = build_scoped_method_call ($1, $2, $3, $5); }
  1185.     | object scoped_identifier identifier_or_opname LEFT_RIGHT
  1186.         { $$ = build_scoped_method_call ($1, $2, $3, NULL_TREE); }
  1187.     ;
  1188.  
  1189. primary_no_id:
  1190.       '(' expr ')'
  1191.         { $$ = $2; }
  1192.     | '(' error ')'
  1193.         { $$ = error_mark_node; }
  1194.     | '('
  1195.         { if (current_function_decl == 0)
  1196.             {
  1197.               error ("braced-group within expression allowed only inside a function");
  1198.               YYERROR;
  1199.             }
  1200.           $<ttype>$ = expand_start_stmt_expr (); }
  1201.       compstmt ')'
  1202.         { if (pedantic)
  1203.             warning ("ANSI C forbids braced-groups within expressions");
  1204.           $$ = expand_end_stmt_expr ($<ttype>2); }
  1205.     | primary_no_id '(' exprlist ')'
  1206.         { $$ = build_x_function_call ($1, $3, current_class_decl); }
  1207.     | primary_no_id LEFT_RIGHT
  1208.         { $$ = build_x_function_call ($1, NULL_TREE, current_class_decl); }
  1209.     | primary_no_id '[' expr ']'
  1210.         { goto do_array; }
  1211.     | primary_no_id PLUSPLUS
  1212.         { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $1); }
  1213.     | primary_no_id MINUSMINUS
  1214.         { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $1); }
  1215.     | SCOPE IDENTIFIER
  1216.         { goto do_scoped_identifier; }
  1217.     | SCOPE operator_name
  1218.         { $2 = hack_operator ($2);
  1219.           if (TREE_CODE ($2) == IDENTIFIER_NODE)
  1220.             goto do_scoped_identifier;
  1221.           goto do_scoped_operator;
  1222.         }
  1223.     ;
  1224.  
  1225. new:      NEW
  1226.         { $$ = NULL_TREE; }
  1227.     | NEW '{' nonnull_exprlist '}'
  1228.         { $$ = $3; }
  1229.     | NEW DYNAMIC  %prec EMPTY
  1230.         { $$ = void_type_node; }
  1231.     | NEW DYNAMIC '(' string ')'
  1232.         { $$ = combine_strings ($4); }
  1233.     | SCOPE new
  1234.         { if ($2 != NULL_TREE
  1235.               && TREE_CODE ($2) == TREE_LIST
  1236.               && TREE_PURPOSE ($2) != NULL_TREE)
  1237.             error ("extra `::' before `new' ignored");
  1238.           else
  1239.             $$ = build_tree_list (error_mark_node, $2);
  1240.         }
  1241.     ;
  1242.  
  1243. delete:      DELETE
  1244.         { $$ = NULL_TREE; }
  1245.     | SCOPE delete
  1246.         { if ($2)
  1247.             error ("extra `::' before `delete' ignored");
  1248.           $$ = error_mark_node;
  1249.         }
  1250.     ;
  1251.  
  1252. /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
  1253. string:
  1254.       STRING
  1255.     | string STRING
  1256.         { $$ = chainon ($1, $2); }
  1257.     ;
  1258.  
  1259. nodecls:
  1260.       /* empty */
  1261.         {
  1262.           if (! current_function_parms_stored)
  1263.             store_parm_decls ();
  1264.           setup_vtbl_ptr ();
  1265.         }
  1266.     ;
  1267.  
  1268. object:      primary '.'
  1269.         {
  1270.           if ($1 == error_mark_node)
  1271.             $$ = error_mark_node;
  1272.           else
  1273.             {
  1274.               tree type = TREE_TYPE ($1);
  1275.  
  1276.               if (IS_AGGR_TYPE (type)
  1277.               || (TREE_CODE (type) == REFERENCE_TYPE
  1278.                   && IS_AGGR_TYPE (TREE_TYPE (type))))
  1279.             $$ = $1;
  1280.               else
  1281.             {
  1282.               error ("object in '.' expression is not of aggregate type");
  1283.               $$ = error_mark_node;
  1284.             }
  1285.             }
  1286.         }
  1287.     | primary POINTSAT
  1288.         {
  1289.           $$ = build_x_arrow ($1);
  1290.         }
  1291.     ;
  1292.  
  1293. decl:
  1294.       typed_declspecs initdecls ';'
  1295.         {
  1296.           resume_momentary ($2);
  1297.           note_got_semicolon ($1);
  1298.         }
  1299.     /* Normal case: make this fast.  */
  1300.     | typed_declspecs declarator ';'
  1301.         { tree d;
  1302.           int yes = suspend_momentary ();
  1303.           d = start_decl ($2, $1, 0, NULL_TREE);
  1304.           finish_decl (d, NULL_TREE, NULL_TREE);
  1305.           resume_momentary (yes);
  1306.           note_got_semicolon ($1);
  1307.         }
  1308.     | declmods notype_initdecls ';'
  1309.         { resume_momentary ($2); }
  1310.     /* Normal case: make this fast.  */
  1311.     | declmods declarator ';'
  1312.         { tree d;
  1313.           int yes = suspend_momentary ();
  1314.           d = start_decl ($2, $1, 0, NULL_TREE);
  1315.           finish_decl (d, NULL_TREE, NULL_TREE);
  1316.           resume_momentary (yes);
  1317.         }
  1318.     | typed_declspecs ';'
  1319.         {
  1320.           shadow_tag ($1);
  1321.           note_got_semicolon ($1);
  1322.         }
  1323.     | declmods ';'
  1324.         { warning ("empty declaration"); }
  1325.     ;
  1326.  
  1327. /* Any kind of declarator (thus, all declarators allowed
  1328.    after an explicit typespec).  */
  1329.  
  1330. declarator:
  1331.       after_type_declarator
  1332.     | notype_declarator
  1333.     ;
  1334.  
  1335. /* Declspecs which contain at least one type specifier or typedef name.
  1336.    (Just `const' or `volatile' is not enough.)
  1337.    A typedef'd name following these is taken as a name to be declared.  */
  1338.  
  1339. typed_declspecs:
  1340.       x_typespec
  1341.         { $$ = list_hash_lookup_or_cons ($1); }
  1342.     | declmods typespec
  1343.         { $$ = hash_tree_chain ($2, $1); }
  1344.     | x_typespec reserved_declspecs
  1345.         { $$ = hash_tree_chain ($1, $2); }
  1346.     | declmods typespec reserved_declspecs
  1347.         { $$ = hash_tree_chain ($2, chainon ($3, $1)); }
  1348.     ;
  1349.  
  1350. reserved_declspecs:  /* empty
  1351.         { $$ = NULL_TREE; } */
  1352.       typespecqual_reserved
  1353.         { $$ = build_decl_list (NULL_TREE, $1); }
  1354.     | SCSPEC
  1355.         { $$ = build_decl_list (NULL_TREE, $1); }
  1356.     | reserved_declspecs typespecqual_reserved
  1357.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1358.     | reserved_declspecs SCSPEC
  1359.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1360.     ;
  1361.  
  1362. /* List of just storage classes and type modifiers.
  1363.    A declaration can start with just this, but then it cannot be used
  1364.    to redeclare a typedef-name.  */
  1365.  
  1366. declmods:
  1367.       dummy_decl TYPE_QUAL
  1368.         { $$ = list_hash_lookup_or_cons ($2); }
  1369.     | dummy_decl SCSPEC
  1370.         { $$ = list_hash_lookup_or_cons ($2); }
  1371.     | declmods TYPE_QUAL
  1372.         { $$ = hash_tree_chain ($2, $1); }
  1373.     | declmods SCSPEC
  1374.         { $$ = hash_tree_chain ($2, $1); }
  1375.     ;
  1376.  
  1377.  
  1378. /* Used instead of declspecs where storage classes are not allowed
  1379.    (that is, for typenames and structure components).
  1380.  
  1381.    C++ can takes storage classes for structure components.
  1382.    Don't accept a typedef-name if anything but a modifier precedes it.  */
  1383.  
  1384. typed_typespecs:
  1385.       x_typespec  %prec EMPTY
  1386.         { $$ = build_decl_list (NULL_TREE, $1); }
  1387.     | nonempty_type_quals typespec
  1388.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1389.     | x_typespec reserved_typespecquals
  1390.         { $$ = decl_tree_cons (NULL_TREE, $1, $2); }
  1391.     | nonempty_type_quals typespec reserved_typespecquals
  1392.         { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $1)); }
  1393.     ;
  1394.  
  1395. reserved_typespecquals:
  1396.       typespecqual_reserved
  1397.         { $$ = build_decl_list (NULL_TREE, $1); }
  1398.     | reserved_typespecquals typespecqual_reserved
  1399.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1400.     ;
  1401.  
  1402. /* A typespec (but not a type qualifier).
  1403.    Once we have seen one of these in a declaration,
  1404.    if a typedef name appears then it is being redeclared.  */
  1405.  
  1406. typespec: TYPESPEC
  1407.     | structsp
  1408.     | TYPENAME
  1409.     | TYPEOF '(' expr ')'
  1410.         { $$ = TREE_TYPE ($3);
  1411.           if (pedantic)
  1412.             warning ("ANSI C forbids `typeof'"); }
  1413.     | TYPEOF '(' typename ')'
  1414.         { $$ = groktypename ($3);
  1415.           if (pedantic)
  1416.             warning ("ANSI C forbids `typeof'"); }
  1417.     ;
  1418.  
  1419. /* A typespec that is a reserved word, or a type qualifier.  */
  1420.  
  1421. typespecqual_reserved: TYPESPEC
  1422.     | TYPE_QUAL
  1423.     | structsp
  1424.     ;
  1425.  
  1426. x_typespec:
  1427.       dummy_decl TYPESPEC
  1428.         { $$ = $2; }
  1429.     | dummy_decl structsp
  1430.         { $$ = $2; }
  1431.     | dummy_decl TYPENAME
  1432.         { $$ = $2; }
  1433.     | dummy_decl TYPEOF '(' expr ')'
  1434.         { $$ = TREE_TYPE ($4);
  1435.           if (pedantic)
  1436.             warning ("ANSI C forbids `typeof'") }
  1437.     | dummy_decl TYPEOF '(' typename ')'
  1438.         { $$ = groktypename ($4);
  1439.           if (pedantic)
  1440.             warning ("ANSI C forbids `typeof'") }
  1441.     ;
  1442.  
  1443. initdecls:
  1444.       initdcl0
  1445.     | initdecls ',' initdcl
  1446.     ;
  1447.  
  1448. notype_initdecls:
  1449.       notype_initdcl0
  1450.     | notype_initdecls ',' initdcl
  1451.     ;
  1452.  
  1453. maybeasm:
  1454.       /* empty */
  1455.         { $$ = NULL_TREE; }
  1456.     | ASM '(' string ')'
  1457.         { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  1458.           $$ = $3;
  1459.           if (pedantic)
  1460.             warning ("ANSI C forbids use of `asm' keyword");
  1461.         }
  1462.     ;
  1463.  
  1464. initdcl0:
  1465.       declarator maybe_raises maybeasm maybe_attribute '='
  1466.         { current_declspecs = $<ttype>0;
  1467.           $<itype>5 = suspend_momentary ();
  1468.           $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1469.       init
  1470. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1471.         { finish_decl ($<ttype>6, $7, $3);
  1472.           $$ = $<itype>5; }
  1473.     | declarator maybe_raises maybeasm maybe_attribute
  1474.         { tree d;
  1475.           current_declspecs = $<ttype>0;
  1476.           $$ = suspend_momentary ();
  1477.           d = start_decl ($1, current_declspecs, 0, $2);
  1478.           finish_decl (d, NULL_TREE, $3); }
  1479.     ;
  1480.  
  1481. initdcl:
  1482.       declarator maybe_raises maybeasm maybe_attribute '='
  1483.         { $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1484.       init
  1485. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1486.         { finish_decl ($<ttype>6, $7, $3); }
  1487.     | declarator maybe_raises maybeasm maybe_attribute
  1488.         { tree d = start_decl ($1, current_declspecs, 0, $2);
  1489.           finish_decl (d, NULL_TREE, $3); }
  1490.     ;
  1491.  
  1492. notype_initdcl0:
  1493.       notype_declarator maybe_raises maybeasm maybe_attribute '='
  1494.         { current_declspecs = $<ttype>0;
  1495.           $<itype>5 = suspend_momentary ();
  1496.           $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1497.       init
  1498. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1499.         { finish_decl ($<ttype>6, $7, $3);
  1500.           $$ = $<itype>5; }
  1501.     | notype_declarator maybe_raises maybeasm maybe_attribute
  1502.         { tree d;
  1503.           current_declspecs = $<ttype>0;
  1504.           $$ = suspend_momentary ();
  1505.           d = start_decl ($1, current_declspecs, 0, $2);
  1506.           finish_decl (d, NULL_TREE, $3); }
  1507.     ;
  1508.  
  1509. /* the * rules are dummies to accept the Apollo extended syntax
  1510.    so that the header files compile. */
  1511. maybe_attribute:
  1512.     /* empty */
  1513.     { $$ = NULL_TREE; }
  1514.     | ATTRIBUTE '(' '(' attribute_list ')' ')'
  1515.         { $$ = $4; }
  1516.     ;
  1517.  
  1518. attribute_list
  1519.     : attrib
  1520.     | attribute_list ',' attrib
  1521.     ;
  1522.  
  1523. attrib
  1524.     : IDENTIFIER
  1525.     { warning ("`%s' attribute directive ignored",
  1526.            IDENTIFIER_POINTER ($1));
  1527.       $$ = $1; }
  1528.     | IDENTIFIER '(' CONSTANT ')'
  1529.     { /* if not "aligned(1)", then issue warning */
  1530.       if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
  1531.           || TREE_CODE ($3) != INTEGER_CST
  1532.           || TREE_INT_CST_LOW ($3) != 1)
  1533.         warning ("`%s' attribute directive ignored",
  1534.              IDENTIFIER_POINTER ($1));
  1535.       $$ = $1; }
  1536.     | IDENTIFIER '(' identifiers ')'
  1537.     { warning ("`%s' attribute directive ignored",
  1538.            IDENTIFIER_POINTER ($1));
  1539.       $$ = $1; }
  1540.     ;
  1541.  
  1542. identifiers:
  1543.       IDENTIFIER
  1544.         { }
  1545.     | identifiers ',' IDENTIFIER
  1546.         { }
  1547.     ;
  1548.  
  1549. init:
  1550.       expr_no_commas %prec '='
  1551.     | '{' '}'
  1552.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
  1553.           TREE_HAS_CONSTRUCTOR ($$) = 1;
  1554.           if (pedantic)
  1555.             warning ("ANSI C forbids empty initializer braces"); }
  1556.     | '{' initlist '}'
  1557.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
  1558.           TREE_HAS_CONSTRUCTOR ($$) = 1; }
  1559.     | '{' initlist ',' '}'
  1560.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
  1561.           TREE_HAS_CONSTRUCTOR ($$) = 1; }
  1562.     | error
  1563.         { $$ = NULL_TREE; }
  1564.     ;
  1565.  
  1566. /* This chain is built in reverse order,
  1567.    and put in forward order where initlist is used.  */
  1568. initlist:
  1569.       init
  1570.         { $$ = build_tree_list (NULL_TREE, $1); }
  1571.     | initlist ',' init
  1572.         { $$ = tree_cons (NULL_TREE, $3, $1); }
  1573.     ;
  1574.  
  1575. structsp:
  1576.       ENUM identifier '{'
  1577.         { $<itype>3 = suspend_momentary ();
  1578.           $$ = start_enum ($2); }
  1579.       enumlist maybecomma_warn '}'
  1580.         { $$ = finish_enum ($<ttype>4, $5);
  1581.           resume_momentary ($<itype>3);
  1582.           check_for_missing_semicolon ($<ttype>4); }
  1583.     | ENUM '{'
  1584.         { $<itype>2 = suspend_momentary ();
  1585.           $$ = start_enum (make_anon_name ()); }
  1586.       enumlist maybecomma_warn '}'
  1587.         { $$ = finish_enum ($<ttype>3, $4);
  1588.           resume_momentary ($<itype>1);
  1589.           check_for_missing_semicolon ($<ttype>3); }
  1590.     | ENUM identifier
  1591.         { $$ = xref_tag (enum_type_node, $2, NULL_TREE); }
  1592.  
  1593.     /* C++ extensions, merged with C to avoid shift/reduce conflicts */
  1594.     | class_head LC opt.component_decl_list '}'
  1595.         {
  1596.           if (TREE_CODE ($1) == ENUMERAL_TYPE)
  1597.             $$ = $1;
  1598.           else if (CLASSTYPE_DECLARED_EXCEPTION ($1))
  1599.             $$ = finish_exception ($1, $3);
  1600.           else
  1601.             $$ = finish_struct ($1, $3, 0, 0);
  1602.             
  1603.           if ($2 & 1)
  1604.             resume_temporary_allocation ();
  1605.           if ($2 & 2)
  1606.             resume_momentary (1);
  1607.           check_for_missing_semicolon ($$);
  1608.         }
  1609.     | class_head LC opt.component_decl_list '}' ';'
  1610.         { if (TREE_CODE ($1) == ENUMERAL_TYPE)
  1611.             $$ = $1;
  1612.           else if (CLASSTYPE_DECLARED_EXCEPTION ($1))
  1613.             warning ("empty exception declaration\n");
  1614.           else
  1615.             $$ = finish_struct ($1, $3, 1, 1);
  1616.           if ($2 & 1)
  1617.             resume_temporary_allocation ();
  1618.           if ($2 & 2)
  1619.             resume_momentary (1);
  1620.           note_got_semicolon ($$);
  1621.           yyungetc (';', 0); }
  1622.     | class_head  %prec EMPTY
  1623.         { $$ = $1; }
  1624.     ;
  1625.  
  1626. maybecomma:
  1627.       /* empty */
  1628.     | ','
  1629.     ;
  1630.  
  1631. maybecomma_warn:
  1632.       /* empty */
  1633.     | ','
  1634.         { if (pedantic) warning ("comma at end of enumerator list"); }
  1635.     ;
  1636.  
  1637. aggr:      AGGR
  1638.         { $$ = $1; }
  1639.     | DYNAMIC AGGR
  1640.         { $$ = build_tree_list (NULL_TREE, $2); }
  1641.     | DYNAMIC '(' string ')' AGGR
  1642.         { $$ = build_tree_list ($3, $5); }
  1643.     | aggr SCSPEC
  1644.         { error ("storage class specifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1645.         }
  1646.     | aggr TYPESPEC
  1647.         { error ("type specifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1648.         }
  1649.     | aggr TYPE_QUAL
  1650.         { error ("type qualifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1651.         }
  1652.     | aggr AGGR
  1653.         { error ("no body nor ';' separates two class, struct or union declarations");
  1654.         }
  1655.  
  1656. class_head:
  1657.       aggr  %prec EMPTY
  1658.         { $$ = xref_tag ($1, make_anon_name (), NULL_TREE); }
  1659.     | aggr identifier  %prec EMPTY
  1660.         { $$ = xref_tag ($1, $2, NULL_TREE); }
  1661.     | aggr IDENTIFIER ':' base_class_list  %prec EMPTY
  1662.         { $$ = xref_tag ($1, $2, $4); }
  1663.     | aggr TYPENAME_COLON  %prec EMPTY
  1664.         { yyungetc (':', 1);
  1665.           $$ = xref_tag ($1, $2, NULL_TREE); }
  1666.     | aggr TYPENAME_COLON base_class_list  %prec EMPTY
  1667.         { $$ = xref_tag ($1, $2, $3); }
  1668.     ;
  1669.  
  1670. base_class_list:
  1671.       identifier
  1672.         { if (! is_aggr_typedef ($1, 1))
  1673.             $$ = NULL_TREE;
  1674.           else $$ = build_tree_list ((tree)visibility_default, $1); }
  1675.     | base_class_visibility_list identifier
  1676.         { if (! is_aggr_typedef ($2, 1))
  1677.             $$ = NULL_TREE;
  1678.           else $$ = build_tree_list ($1, $2); }
  1679.     | base_class_list ',' identifier
  1680.         { if (! is_aggr_typedef ($3, 1))
  1681.             $$ = NULL_TREE;
  1682.           else $$ = chainon ($1, build_tree_list ((tree)visibility_default, $3)); }
  1683.     | base_class_list ',' base_class_visibility_list identifier
  1684.         { if (! is_aggr_typedef ($4, 1))
  1685.             $$ = NULL_TREE;
  1686.           else $$ = chainon ($1, build_tree_list ($3, $4)); }
  1687.     ;
  1688.  
  1689. base_class_visibility_list:
  1690.       PUBLIC
  1691.         { $$ = (tree)visibility_public; }
  1692.     | PRIVATE
  1693.         { $$ = (tree)visibility_private; }
  1694.     | SCSPEC
  1695.         { if ($1 != ridpointers[(int)RID_VIRTUAL])
  1696.             sorry ("non-virtual visibility");
  1697.           $$ = (tree)visibility_default_virtual; }
  1698.     | base_class_visibility_list PUBLIC
  1699.         { if ($1 == (tree)visibility_private)
  1700.             error ("base class cannot be public and private");
  1701.           else if ($1 == (tree)visibility_default_virtual)
  1702.             $$ = (tree)visibility_public_virtual; }
  1703.     | base_class_visibility_list PRIVATE
  1704.         { if ($1 == (tree)visibility_public)
  1705.             error ("base class cannot be private and public");
  1706.           else if ($1 == (tree)visibility_default_virtual)
  1707.             $$ = (tree)visibility_private_virtual; }
  1708.     | base_class_visibility_list SCSPEC
  1709.         { if ($2 != ridpointers[(int)RID_VIRTUAL])
  1710.             sorry ("non-virtual visibility");
  1711.           if ($1 == (tree)visibility_public)
  1712.             $$ = (tree)visibility_public_virtual;
  1713.           else if ($1 == (tree)visibility_private)
  1714.             $$ = (tree)visibility_private_virtual; }
  1715.     ;
  1716.  
  1717. LC: '{'
  1718.         { int temp = allocation_temporary_p ();
  1719.           int momentary = suspend_momentary ();
  1720.           if (temp)
  1721.             end_temporary_allocation ();
  1722.           $$ = (momentary << 1) | temp;
  1723.           if (! IS_AGGR_TYPE ($<ttype>0))
  1724.             {
  1725.               $<ttype>0 = make_lang_type (RECORD_TYPE);
  1726.               TYPE_NAME ($<ttype>0) = get_identifier ("erroneous type");
  1727.             }
  1728.           pushclass ($<ttype>0, 0); }
  1729.  
  1730. opt.component_decl_list:
  1731.     /* empty */
  1732.         { $$ = NULL_TREE; }
  1733.     | component_decl_list
  1734.         { $$ = build_tree_list ((tree)visibility_default, $1); }
  1735.     | opt.component_decl_list PUBLIC ':' component_decl_list
  1736.         { $$ = chainon ($1, build_tree_list ((tree)visibility_public, $4)); }
  1737.     | opt.component_decl_list PRIVATE ':' component_decl_list
  1738.         { $$ = chainon ($1, build_tree_list ((tree)visibility_private, $4)); }
  1739.     | opt.component_decl_list PROTECTED ':' component_decl_list
  1740.         { $$ = chainon ($1, build_tree_list ((tree)visibility_protected, $4)); }
  1741.     | opt.component_decl_list PUBLIC ':'
  1742.     | opt.component_decl_list PRIVATE ':'
  1743.     | opt.component_decl_list PROTECTED ':'
  1744.     ;
  1745.  
  1746. component_decl_list:
  1747.       component_decl
  1748.         { if ($1 == void_type_node) $$ = NULL_TREE; }
  1749.     | component_decl_list component_decl
  1750.         { if ($2 != NULL_TREE && $2 != void_type_node)
  1751.             $$ = chainon ($1, $2); }
  1752.     | component_decl_list ';'
  1753.         { if (pedantic)
  1754.             warning ("extra semicolon in struct or union specified"); }
  1755.     ;
  1756.  
  1757. component_decl:
  1758.       typed_declspecs components ';'
  1759.         {
  1760.         do_components:
  1761.           if ($2 == void_type_node)
  1762.             /* We just got some friends.
  1763.                They have been recorded elsewhere.  */
  1764.             $$ = NULL_TREE;
  1765.           else if ($2 == NULL_TREE)
  1766.             {
  1767.               tree t = groktypename (build_decl_list ($1, NULL_TREE));
  1768.               if (t == NULL_TREE)
  1769.             {
  1770.               error ("error in component specification");
  1771.               $$ = NULL_TREE;
  1772.             }
  1773.               else if (TREE_CODE (t) == UNION_TYPE)
  1774.             {
  1775.               /* handle anonymous unions */
  1776.               if (CLASSTYPE_METHOD_VEC (t))
  1777.                 sorry ("methods in anonymous unions");
  1778.               $$ = build_lang_field_decl (FIELD_DECL, NULL_TREE, t);
  1779.               DECL_ANON_UNION_ELEM ($$) = 1;
  1780.             }
  1781.               else if (TREE_CODE (t) == ENUMERAL_TYPE)
  1782.             $$ = grok_enum_decls (t, NULL_TREE);
  1783.               else
  1784.             {
  1785.               if (TREE_CODE (t) == RECORD_TYPE
  1786.                   && TYPE_LANG_SPECIFIC (t)
  1787.                   && CLASSTYPE_DECLARED_EXCEPTION (t))
  1788.                 shadow_tag ($1);
  1789.               $$ = NULL_TREE;
  1790.             }
  1791.             }
  1792.           else
  1793.             {
  1794.               tree t = TREE_TYPE ($2);
  1795.               if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL (t))
  1796.             $$ = grok_enum_decls (t, $2);
  1797.               else
  1798.             $$ = $2;
  1799.             }
  1800.           end_exception_decls ();
  1801.         }
  1802.     | typed_declspecs '(' parmlist ')' ';'
  1803.         { $$ = groktypefield ($1, $3); }
  1804.     | typed_declspecs '(' parmlist ')' '}'
  1805.         { error ("missing ';' before right brace");
  1806.           yyungetc ('}', 0);
  1807.           $$ = groktypefield ($1, $3); }
  1808.     | typed_declspecs LEFT_RIGHT ';'
  1809.         { $$ = groktypefield ($1, empty_parms ()); }
  1810.     | typed_declspecs LEFT_RIGHT '}'
  1811.         { error ("missing ';' before right brace");
  1812.           yyungetc ('}', 0);
  1813.           $$ = groktypefield ($1, empty_parms ()); }
  1814.     | declmods components ';'
  1815.         { goto do_components; }
  1816.     /* Normal case: make this fast.  */
  1817.     | declmods declarator ';'
  1818.         { $$ = grokfield ($2, $1, 0, 0, 0, 0); }
  1819.     | declmods components '}'
  1820.         { error ("missing ';' before right brace");
  1821.           yyungetc ('}', 0);
  1822.           goto do_components; }
  1823.     | declmods '(' parmlist ')' ';'
  1824.         { $$ = groktypefield ($1, $3); }
  1825.     | declmods '(' parmlist ')' '}'
  1826.         { error ("missing ';' before right brace");
  1827.           yyungetc ('}', 0);
  1828.           $$ = groktypefield ($1, $3); }
  1829.     | declmods LEFT_RIGHT ';'
  1830.         { $$ = groktypefield ($1, empty_parms ()); }
  1831.     | declmods LEFT_RIGHT '}'
  1832.         { error ("missing ';' before right brace");
  1833.           yyungetc ('}', 0);
  1834.           $$ = groktypefield ($1, empty_parms ()); }
  1835.     | ':' expr_no_commas ';'
  1836.         { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1837.     | ':' expr_no_commas '}'
  1838.         { error ("missing ';' before right brace");
  1839.           yyungetc ('}', 0);
  1840.           $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1841.     | error
  1842.         { $$ = NULL_TREE; }
  1843.  
  1844.     /* C++: handle constructors, destructors and inline functions */
  1845.     /* note that INLINE is like a TYPESPEC */
  1846.     | fn.def2 ':' /* base_init compstmt */
  1847.         { $$ = finish_method ($1); }
  1848.     | fn.def2 '{' /* nodecls compstmt */
  1849.         { $$ = finish_method ($1); }
  1850.     | dummy_decl notype_declarator maybe_raises ';'
  1851.         { $$ = grokfield ($2, NULL_TREE, $3, NULL_TREE, NULL_TREE); }
  1852.     | dummy_decl notype_declarator maybe_raises '}'
  1853.         { error ("missing ';' before right brace");
  1854.           yyungetc ('}', 0);
  1855.           $$ = grokfield ($2, NULL_TREE, $3, NULL_TREE, NULL_TREE); }
  1856.     ;
  1857.  
  1858. components:
  1859.       /* empty: possibly anonymous */
  1860.         { $$ = NULL_TREE; }
  1861.     | component_declarator0
  1862.     | components ',' component_declarator
  1863.         {
  1864.           /* In this context, void_type_node encodes
  1865.              friends.  They have been recorded elsewhere.  */
  1866.           if ($1 == void_type_node)
  1867.             $$ = $3;
  1868.           else
  1869.             $$ = chainon ($1, $3);
  1870.         }
  1871.     ;
  1872.  
  1873. component_declarator0:
  1874.       declarator maybe_raises maybeasm opt.init
  1875.         { current_declspecs = $<ttype>0;
  1876.           $$ = grokfield ($1, current_declspecs, $2, $4, $3); }
  1877.     | IDENTIFIER ':' expr_no_commas
  1878.         { current_declspecs = $<ttype>0;
  1879.           $$ = grokbitfield ($1, current_declspecs, $3); }
  1880.     | TYPENAME_COLON expr_no_commas
  1881.         { current_declspecs = $<ttype>0;
  1882.           $$ = grokbitfield ($1, current_declspecs, $2); }
  1883.     | ':' expr_no_commas
  1884.         { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1885.     ;
  1886.  
  1887. component_declarator:
  1888.       declarator maybe_raises maybeasm opt.init
  1889.         { $$ = grokfield ($1, current_declspecs, $2, $4, $3); }
  1890.     | IDENTIFIER ':' expr_no_commas
  1891.         { $$ = grokbitfield ($1, current_declspecs, $3); }
  1892.     | TYPENAME_COLON expr_no_commas
  1893.         { $$ = grokbitfield ($1, current_declspecs, $2); }
  1894.     | ':' expr_no_commas
  1895.         { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  1896.     ;
  1897.  
  1898. /* We chain the enumerators in reverse order.
  1899.    Because of the way enums are built, the order is
  1900.    insignificant.  Take advantage of this fact.  */
  1901.  
  1902. enumlist:
  1903.       enumerator
  1904.     | enumlist ',' enumerator
  1905.         { TREE_CHAIN ($3) = $1; $$ = $3; }
  1906.     ;
  1907.  
  1908. enumerator:
  1909.       identifier
  1910.         { $$ = build_enumerator ($1, NULL_TREE); }
  1911.     | identifier '=' expr_no_commas
  1912.         { $$ = build_enumerator ($1, $3); }
  1913.     ;
  1914.  
  1915. typename:
  1916.       typed_typespecs absdcl
  1917.         { $$ = build_decl_list ($1, $2); }
  1918.     | nonempty_type_quals absdcl
  1919.         { $$ = build_decl_list ($1, $2); }
  1920.     ;
  1921.  
  1922. absdcl:   /* an abstract declarator */
  1923.     /* empty */ %prec EMPTY
  1924.         { $$ = NULL_TREE; }
  1925.     | absdcl1  %prec EMPTY
  1926.     ;
  1927.  
  1928. nonempty_type_quals:
  1929.       dummy_decl TYPE_QUAL
  1930.         { $$ = build_decl_list (NULL_TREE, $2); }
  1931.     | nonempty_type_quals TYPE_QUAL
  1932.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1933.     ;
  1934.  
  1935. type_quals:
  1936.       /* empty */
  1937.         { $$ = NULL_TREE; }
  1938.     | type_quals TYPE_QUAL
  1939.         { $$ = decl_tree_cons (NULL_TREE, $2, $1); }
  1940.     ;
  1941.  
  1942. /* These rules must follow the rules for function declarations
  1943.    and component declarations.  That way, longer rules are prefered.  */
  1944.  
  1945. /* An expression which will not live on the momentary obstack.  */
  1946. nonmomentary_expr:
  1947.     { $<itype>$ = suspend_momentary (); } expr
  1948.     { resume_momentary ($<itype>1); $$ = $2; }
  1949.  
  1950. /* A declarator that is allowed only after an explicit typespec.  */
  1951. /* may all be followed by prec '.' */
  1952. after_type_declarator:
  1953.       after_type_declarator '(' nonnull_exprlist ')' type_quals  %prec '.'
  1954.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1955.     | after_type_declarator '(' parmlist ')' type_quals  %prec '.'
  1956.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1957.     | after_type_declarator LEFT_RIGHT type_quals  %prec '.'
  1958.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  1959.     | after_type_declarator '(' error ')' type_quals  %prec '.'
  1960.         { $$ = build_parse_node (CALL_EXPR, $1, NULL_TREE, NULL_TREE); }
  1961.     | after_type_declarator '[' nonmomentary_expr ']'
  1962.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  1963.     | after_type_declarator '[' ']'
  1964.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  1965.     | '(' dummy_decl after_type_declarator_no_typename ')'
  1966.         { $$ = $3; }
  1967.     | '(' '*' type_quals after_type_declarator ')'
  1968.         { $$ = make_pointer_declarator ($3, $4); }
  1969.     | PAREN_STAR_PAREN
  1970.         { $$ = $1;
  1971.           see_typename (); }
  1972.     | PAREN_X_SCOPE_STAR_PAREN
  1973.         { $$ = $1;
  1974.           see_typename (); }
  1975.     | PAREN_X_SCOPE_REF_PAREN
  1976.         { $$ = $1;
  1977.           see_typename (); }
  1978.     | '(' '&' type_quals after_type_declarator ')'
  1979.         { $$ = make_reference_declarator ($3, $4); }
  1980.     | '*' type_quals after_type_declarator  %prec UNARY
  1981.         { $$ = make_pointer_declarator ($2, $3); }
  1982.     | '&' type_quals after_type_declarator  %prec UNARY
  1983.         { $$ = make_reference_declarator ($2, $3); }
  1984.     | TYPENAME
  1985.     ;
  1986.  
  1987. after_type_declarator_no_typename:
  1988.       after_type_declarator_no_typename '(' nonnull_exprlist ')' type_quals  %prec '.'
  1989.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1990.     | after_type_declarator_no_typename '(' parmlist ')' type_quals  %prec '.'
  1991.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  1992.     | after_type_declarator_no_typename LEFT_RIGHT type_quals  %prec '.'
  1993.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  1994.     | after_type_declarator_no_typename '(' error ')' type_quals  %prec '.'
  1995.         { $$ = build_parse_node (CALL_EXPR, $1, NULL_TREE, NULL_TREE); }
  1996.     | after_type_declarator_no_typename '[' nonmomentary_expr ']'
  1997.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  1998.     | after_type_declarator_no_typename '[' ']'
  1999.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  2000.     | '(' dummy_decl after_type_declarator_no_typename ')'
  2001.         { $$ = $3; }
  2002.     | PAREN_STAR_PAREN
  2003.         { $$ = $1;
  2004.           see_typename (); }
  2005.     | PAREN_X_SCOPE_STAR_PAREN
  2006.         { $$ = $1;
  2007.           see_typename (); }
  2008.     | PAREN_X_SCOPE_REF_PAREN
  2009.         { $$ = $1;
  2010.           see_typename (); }
  2011.     | '*' type_quals after_type_declarator  %prec UNARY
  2012.         { $$ = make_pointer_declarator ($2, $3); }
  2013.     | '&' type_quals after_type_declarator  %prec UNARY
  2014.         { $$ = make_reference_declarator ($2, $3); }
  2015.     ;
  2016.  
  2017. /* A declarator allowed whether or not there has been
  2018.    an explicit typespec.  These cannot redeclare a typedef-name.  */
  2019.  
  2020. notype_declarator:
  2021.       notype_declarator '(' nonnull_exprlist ')' type_quals  %prec '.'
  2022.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  2023.     | notype_declarator '(' parmlist ')' type_quals  %prec '.'
  2024.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  2025.     | notype_declarator LEFT_RIGHT type_quals  %prec '.'
  2026.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  2027.     | notype_declarator '(' error ')' type_quals  %prec '.'
  2028.         { $$ = build_parse_node (CALL_EXPR, $1, NULL_TREE, NULL_TREE); }
  2029.     | '(' notype_declarator ')'
  2030.         { $$ = $2; }
  2031.     | '*' type_quals notype_declarator  %prec UNARY
  2032.         { $$ = make_pointer_declarator ($2, $3); }
  2033.     | '&' type_quals notype_declarator  %prec UNARY
  2034.         { $$ = make_reference_declarator ($2, $3); }
  2035.     | notype_declarator '[' nonmomentary_expr ']'
  2036.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  2037.     | notype_declarator '[' ']'
  2038.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  2039.     | IDENTIFIER
  2040.         { see_typename (); }
  2041.  
  2042.     /* C++ extensions.  */
  2043.     | operator_name
  2044.         { see_typename (); }
  2045.  
  2046.     | '~' TYPENAME
  2047.         { see_typename ();
  2048.           $$ = build_parse_node (BIT_NOT_EXPR, $2); }
  2049.     | '~' IDENTIFIER
  2050.         { see_typename ();
  2051.           $$ = build_parse_node (BIT_NOT_EXPR, $2); }
  2052.     | LEFT_RIGHT identifier
  2053.         {
  2054.           see_typename ();
  2055.           $$ = build_parse_node (WRAPPER_EXPR, $2);
  2056.         }
  2057.     | LEFT_RIGHT '?' identifier
  2058.         {
  2059.           see_typename ();
  2060.           $$ = build_parse_node (WRAPPER_EXPR,
  2061.                  build_parse_node (COND_EXPR, $3, NULL_TREE, NULL_TREE));
  2062.         }
  2063.     | '~' LEFT_RIGHT identifier
  2064.         { see_typename ();
  2065.           $$ = build_parse_node (ANTI_WRAPPER_EXPR, $3); }
  2066.     | TYPENAME_SCOPE type_quals notype_declarator  %prec '('
  2067.         { see_typename ();
  2068.           $$ = build_parse_node (SCOPE_REF, $1, $3); }
  2069.     | TYPENAME_SCOPE TYPENAME  %prec '('
  2070.         { $$ = build_parse_node (SCOPE_REF, $1, $2); }
  2071.     | TYPENAME_SCOPE see_typename TYPENAME '(' nonnull_exprlist ')' type_quals  %prec '.'
  2072.         { $$ = build_parse_node (SCOPE_REF, $1,
  2073.                  build_parse_node (CALL_EXPR, $3, $5, $7)); }
  2074.     | TYPENAME_SCOPE see_typename TYPENAME '(' parmlist ')' type_quals  %prec '.'
  2075.         { $$ = build_parse_node (SCOPE_REF, $1,
  2076.                  build_parse_node (CALL_EXPR, $3, $5, $7)); }
  2077.     | TYPENAME_SCOPE see_typename TYPENAME LEFT_RIGHT type_quals  %prec '.'
  2078.         { $$ = build_parse_node (SCOPE_REF, $1,
  2079.                  build_parse_node (CALL_EXPR, $3, empty_parms (), $5)); }
  2080.     | TYPENAME_SCOPE see_typename TYPENAME '(' error ')' type_quals  %prec '.'
  2081.         { $$ = build_parse_node (SCOPE_REF, $1, build_parse_node (CALL_EXPR, $3, NULL_TREE, NULL_TREE)); }
  2082.     | SCOPE see_typename notype_declarator
  2083.         { $$ = build_parse_node (SCOPE_REF, NULL_TREE, $3); }
  2084.     ;
  2085.  
  2086. scoped_identifier:
  2087.       TYPENAME_SCOPE
  2088.     | IDENTIFIER SCOPE
  2089.     | scoped_identifier TYPENAME_SCOPE
  2090.         { $$ = build_parse_node (SCOPE_REF, $1, $2); }
  2091.     ;
  2092.  
  2093. absdcl1:  /* a nonempty abstract declarator */
  2094.       '(' absdcl1 ')'
  2095.         { see_typename ();
  2096.           $$ = $2; }
  2097.       /* `(typedef)1' is `int'.  */
  2098.     | '*' type_quals absdcl1  %prec EMPTY
  2099.         { $$ = make_pointer_declarator ($2, $3); }
  2100.     | '*' type_quals  %prec EMPTY
  2101.         { $$ = make_pointer_declarator ($2, NULL_TREE); }
  2102.     | PAREN_STAR_PAREN
  2103.         { $$ = $1;
  2104.           see_typename (); }
  2105.     | PAREN_X_SCOPE_STAR_PAREN
  2106.         { $$ = $1;
  2107.           see_typename (); }
  2108.     | PAREN_X_SCOPE_REF_PAREN
  2109.         { $$ = $1;
  2110.           see_typename (); }
  2111.     | '&' type_quals absdcl1 %prec EMPTY
  2112.         { $$ = make_reference_declarator ($2, $3); }
  2113.     | '&' type_quals %prec EMPTY
  2114.         { $$ = make_reference_declarator ($2, NULL_TREE); }
  2115.     | absdcl1 '(' parmlist ')' type_quals  %prec '.'
  2116.         { $$ = build_parse_node (CALL_EXPR, $1, $3, $5); }
  2117.     | absdcl1 LEFT_RIGHT type_quals  %prec '.'
  2118.         { $$ = build_parse_node (CALL_EXPR, $1, empty_parms (), $3); }
  2119.     | absdcl1 '[' nonmomentary_expr ']'  %prec '.'
  2120.         { $$ = build_parse_node (ARRAY_REF, $1, $3); }
  2121.     | absdcl1 '[' ']'  %prec '.'
  2122.         { $$ = build_parse_node (ARRAY_REF, $1, NULL_TREE); }
  2123.     | '(' parmlist ')' type_quals  %prec '.'
  2124.         { $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, $4); }
  2125.     | LEFT_RIGHT type_quals  %prec '.'
  2126.         { $$ = build_parse_node (CALL_EXPR, NULL_TREE, empty_parms (), $2); }
  2127.     | '[' nonmomentary_expr ']'  %prec '.'
  2128.         { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); }
  2129.     | '[' ']'  %prec '.'
  2130.         { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); }
  2131.     | TYPENAME_SCOPE type_quals absdcl1  %prec EMPTY
  2132.         { $$ = build_parse_node (SCOPE_REF, $1, $3); }
  2133.     | IDENTIFIER SCOPE type_quals absdcl1  %prec EMPTY
  2134.         { $$ = build_parse_node (SCOPE_REF, $1, $4); }
  2135.     | TYPENAME_SCOPE type_quals %prec EMPTY
  2136.         { $$ = build_parse_node (SCOPE_REF, $1, 0); }
  2137.     | IDENTIFIER SCOPE type_quals %prec EMPTY
  2138.         { $$ = build_parse_node (SCOPE_REF, $1, 0); }
  2139.     ;
  2140.  
  2141. /* at least one statement, the first of which parses without error.  */
  2142. /* stmts is used only after decls, so an invalid first statement
  2143.    is actually regarded as an invalid decl and part of the decls.  */
  2144.  
  2145. stmts:
  2146.       stmt
  2147.     | stmts stmt
  2148.     | stmts errstmt
  2149.     ;
  2150.  
  2151. errstmt:  error ';'
  2152.     ;
  2153.  
  2154. /* build the LET_STMT node before parsing its contents,
  2155.   so that any LET_STMTs within the context can have their display pointers
  2156.   set up to point at this one.  */
  2157.  
  2158. .pushlevel:  /* empty */
  2159.         {
  2160.           pushlevel (0);
  2161.           clear_last_expr ();
  2162.           push_momentary ();
  2163.           expand_start_bindings (0);
  2164.           stmt_decl_msg = 0;
  2165.         }
  2166.     ;
  2167.  
  2168. /* This is the body of a function definition.
  2169.    It causes syntax errors to ignore to the next openbrace.  */
  2170. compstmt_or_error:
  2171.       compstmt
  2172.         {}
  2173.     | error compstmt
  2174.     ;
  2175.  
  2176. compstmt: '{' '}'
  2177.         { $$ = 0; }
  2178.     | '{' .pushlevel stmts '}'
  2179.         { tree decls;
  2180.  
  2181.           pop_implicit_try_blocks (NULL_TREE);
  2182.           decls = getdecls ();
  2183.           expand_end_bindings (decls, decls != 0, 1);
  2184.           $$ = poplevel (decls != 0, 1, 0);
  2185.           pop_momentary (); }
  2186.     | '{' .pushlevel error '}'
  2187.         { pop_implicit_try_blocks (NULL_TREE);
  2188.           expand_end_bindings (getdecls (), 0, 1);
  2189.           $$ = poplevel (0, 0, 0);
  2190.           pop_momentary (); }
  2191.     ;
  2192.  
  2193. simple_if:
  2194.       IF '(' expr ')'
  2195.         { emit_line_note (input_filename, lineno);
  2196.           expand_start_cond (truthvalue_conversion ($3), 0);
  2197.           stmt_decl_msg = "if"; }
  2198.       stmt
  2199.         { stmt_decl_msg = 0; }
  2200.     ;
  2201.  
  2202. stmt:
  2203.       compstmt
  2204.         { finish_stmt (); }
  2205.     | decl
  2206.         { if (stmt_decl_msg)
  2207.             error ("declaration after %s invalid", stmt_decl_msg);
  2208.           stmt_decl_msg = 0;
  2209.           finish_stmt (); }
  2210.     | expr ';'
  2211.         { emit_line_note (input_filename, lineno);
  2212.           /* Do default conversion if safe and possibly important,
  2213.              in case within ({...}).  */
  2214.           if ((TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
  2215.                && lvalue_p ($1))
  2216.               || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
  2217.             $1 = default_conversion ($1);
  2218.           expand_cplus_expr_stmt ($1);
  2219.           clear_momentary ();
  2220.           finish_stmt (); }
  2221.     | simple_if ELSE
  2222.         { expand_start_else ();
  2223.           stmt_decl_msg = "else"; }
  2224.       stmt
  2225.         { expand_end_else ();
  2226.           stmt_decl_msg = 0;
  2227.           finish_stmt (); }
  2228.     | simple_if %prec IF
  2229.         { expand_end_cond ();
  2230.           stmt_decl_msg = 0;
  2231.           finish_stmt (); }
  2232.     | WHILE
  2233.         { emit_nop ();
  2234.           emit_line_note (input_filename, lineno);
  2235.           expand_start_loop (1); }
  2236.       '(' expr ')'
  2237.         { expand_exit_loop_if_false (truthvalue_conversion ($4));
  2238.           stmt_decl_msg = "while"; }
  2239.       stmt
  2240.         { 
  2241.           expand_end_loop ();
  2242.           stmt_decl_msg = 0;
  2243.           finish_stmt (); }
  2244.     | DO
  2245.         { emit_nop ();
  2246.           emit_line_note (input_filename, lineno);
  2247.           expand_start_loop_continue_elsewhere (1);
  2248.           stmt_decl_msg = "do"; }
  2249.       stmt WHILE
  2250.         { stmt_decl_msg = 0;
  2251.           expand_loop_continue_here (); }
  2252.       '(' expr ')' ';'
  2253.         { emit_line_note (input_filename, lineno);
  2254.           expand_exit_loop_if_false (truthvalue_conversion ($7));
  2255.           expand_end_loop ();
  2256.           clear_momentary ();
  2257.           finish_stmt (); }
  2258.     | forhead.1
  2259.         { emit_nop ();
  2260.           emit_line_note (input_filename, lineno);
  2261.           if ($1) expand_cplus_expr_stmt ($1);
  2262.           expand_start_loop_continue_elsewhere (1); }
  2263.       xexpr ';'
  2264.         { emit_line_note (input_filename, lineno);
  2265.           if ($3) expand_exit_loop_if_false (truthvalue_conversion ($3)); }
  2266.       xexpr ')'
  2267.         /* Don't let the tree nodes for $6 be discarded
  2268.            by clear_momentary during the parsing of the next stmt.  */
  2269.         { push_momentary ();
  2270.           stmt_decl_msg = "for"; }
  2271.       stmt
  2272.         { emit_line_note (input_filename, lineno);
  2273.           expand_loop_continue_here ();
  2274.           if ($6) expand_cplus_expr_stmt ($6);
  2275.           pop_momentary ();
  2276.           expand_end_loop ();
  2277.           stmt_decl_msg = 0;
  2278.           finish_stmt (); }
  2279.     | forhead.2
  2280.         { emit_nop ();
  2281.           emit_line_note (input_filename, lineno);
  2282.           expand_start_loop_continue_elsewhere (1); }
  2283.       xexpr ';'
  2284.         { emit_line_note (input_filename, lineno);
  2285.           if ($3) expand_exit_loop_if_false (truthvalue_conversion ($3)); }
  2286.       xexpr ')'
  2287.         /* Don't let the tree nodes for $6 be discarded
  2288.            by clear_momentary during the parsing of the next stmt.  */
  2289.         { push_momentary ();
  2290.           stmt_decl_msg = "for";
  2291.           $<itype>7 = lineno; }
  2292.       stmt
  2293.         { emit_line_note (input_filename, $<itype>7);
  2294.           expand_loop_continue_here ();
  2295.           if ($6) expand_cplus_expr_stmt ($6);
  2296.           pop_momentary ();
  2297.           expand_end_loop ();
  2298.           pop_implicit_try_blocks (NULL_TREE);
  2299.           if ($1)
  2300.             {
  2301.               register keep = $1 > 0;
  2302.               if (keep) expand_end_bindings (0, keep, 1);
  2303.               poplevel (keep, 1, 0);
  2304.               pop_momentary ();
  2305.             }
  2306.           stmt_decl_msg = 0;
  2307.           finish_stmt ();
  2308.         }
  2309.     | SWITCH '(' expr ')'
  2310.         { emit_line_note (input_filename, lineno);
  2311.           c_expand_start_case ($3);
  2312.           /* Don't let the tree nodes for $3 be discarded by
  2313.              clear_momentary during the parsing of the next stmt.  */
  2314.           push_momentary ();
  2315.           stmt_decl_msg = "switch"; }
  2316.       stmt
  2317.         { expand_end_case ($3);
  2318.           pop_momentary ();
  2319.           stmt_decl_msg = 0;
  2320.           finish_stmt (); }
  2321.     | CASE expr ':'
  2322.         { register tree value = $2;
  2323.           register tree label
  2324.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2325.  
  2326.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2327.              Strip such NOP_EXPRs.  */
  2328.           if (TREE_CODE (value) == NOP_EXPR
  2329.               && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
  2330.             value = TREE_OPERAND (value, 0);
  2331.  
  2332.           if (TREE_READONLY (value) && TREE_CODE (value) == VAR_DECL)
  2333.             {
  2334.               value = decl_constant_value (value);
  2335.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2336.              Strip such NOP_EXPRs.  */
  2337.               if (TREE_CODE (value) == NOP_EXPR
  2338.               && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
  2339.             value = TREE_OPERAND (value, 0);
  2340.             }
  2341.           value = fold (value);
  2342.  
  2343.           if (TREE_CODE (value) != INTEGER_CST
  2344.               && value != error_mark_node)
  2345.             {
  2346.               error ("case label does not reduce to an integer constant");
  2347.               value = error_mark_node;
  2348.             }
  2349.           else
  2350.             /* Promote char or short to int.  */
  2351.             value = default_conversion (value);
  2352.           if (value != error_mark_node)
  2353.             {
  2354.               int success = pushcase (value, label);
  2355.               if (success == 1)
  2356.             error ("case label not within a switch statement");
  2357.               else if (success == 2)
  2358.             error ("duplicate case value");
  2359.               else if (success == 3)
  2360.             warning ("case value out of range");
  2361.             }
  2362.           define_case_label (label);
  2363.         }
  2364.       stmt
  2365.     | CASE expr RANGE expr ':'
  2366.         { register tree value1 = $2;
  2367.           register tree value2 = $4;
  2368.           register tree label
  2369.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2370.  
  2371.           if (pedantic)
  2372.             {
  2373.               error ("ANSI C does not allow range expressions in switch statement");
  2374.               value1 = error_mark_node;
  2375.               value2 = error_mark_node;
  2376.               break;
  2377.             }
  2378.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2379.              Strip such NOP_EXPRs.  */
  2380.           if (TREE_CODE (value1) == NOP_EXPR
  2381.               && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
  2382.             value1 = TREE_OPERAND (value1, 0);
  2383.  
  2384.           if (TREE_READONLY (value1) && TREE_CODE (value1) == VAR_DECL)
  2385.             {
  2386.               value1 = decl_constant_value (value1);
  2387.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2388.              Strip such NOP_EXPRs.  */
  2389.               if (TREE_CODE (value1) == NOP_EXPR
  2390.               && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
  2391.             value1 = TREE_OPERAND (value1, 0);
  2392.             }
  2393.           value1 = fold (value1);
  2394.  
  2395.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2396.              Strip such NOP_EXPRs.  */
  2397.           if (TREE_CODE (value2) == NOP_EXPR
  2398.               && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
  2399.             value2 = TREE_OPERAND (value2, 0);
  2400.  
  2401.           if (TREE_READONLY (value2) && TREE_CODE (value2) == VAR_DECL)
  2402.             {
  2403.               value2 = decl_constant_value (value2);
  2404.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2405.              Strip such NOP_EXPRs.  */
  2406.               if (TREE_CODE (value2) == NOP_EXPR
  2407.               && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
  2408.             value2 = TREE_OPERAND (value2, 0);
  2409.             }
  2410.           value2 = fold (value2);
  2411.  
  2412.  
  2413.           if (TREE_CODE (value1) != INTEGER_CST
  2414.               && value1 != error_mark_node)
  2415.             {
  2416.               error ("case label does not reduce to an integer constant");
  2417.               value1 = error_mark_node;
  2418.             }
  2419.           if (TREE_CODE (value2) != INTEGER_CST
  2420.               && value2 != error_mark_node)
  2421.             {
  2422.               error ("case label does not reduce to an integer constant");
  2423.               value2 = error_mark_node;
  2424.             }
  2425.           if (value1 != error_mark_node
  2426.               && value2 != error_mark_node)
  2427.             {
  2428.               int success = pushcase_range (value1, value2, label);
  2429.               if (success == 1)
  2430.             error ("case label not within a switch statement");
  2431.               else if (success == 2)
  2432.             error ("duplicate (or overlapping) case value");
  2433.               else if (success == 3)
  2434.             warning ("case value out of range");
  2435.               else if (success == 4)
  2436.             warning ("empty range specified");
  2437.             }
  2438.           define_case_label (label);
  2439.         }
  2440.       stmt
  2441.     | DEFAULT ':'
  2442.         {
  2443.           register tree label
  2444.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2445.           int success = pushcase (NULL_TREE, label);
  2446.           if (success == 1)
  2447.             error ("default label not within a switch statement");
  2448.           else if (success == 2)
  2449.             error ("multiple default labels in one switch");
  2450.         }
  2451.       stmt
  2452.     | BREAK ';'
  2453.         { emit_line_note (input_filename, lineno);
  2454.           if ( ! expand_exit_something ())
  2455.             error ("break statement not within loop or switch"); }
  2456.     | CONTINUE ';'
  2457.         { emit_line_note (input_filename, lineno);
  2458.           if (! expand_continue_loop ())
  2459.             error ("continue statement not within a loop"); }
  2460.     | RETURN ';'
  2461.         { emit_line_note (input_filename, lineno);
  2462.           c_expand_return (NULL_TREE); }
  2463.     | RETURN expr ';'
  2464.         { emit_line_note (input_filename, lineno);
  2465.           c_expand_return ($2);
  2466.           finish_stmt ();
  2467.         }
  2468.     | ASM maybe_type_qual '(' string ')' ';'
  2469.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2470.           emit_line_note (input_filename, lineno);
  2471.           expand_asm ($4);
  2472.           finish_stmt ();
  2473.         }
  2474.     /* This is the case with just output operands.  */
  2475.     | ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
  2476.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2477.           emit_line_note (input_filename, lineno);
  2478.           c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
  2479.                      $2 == ridpointers[(int)RID_VOLATILE],
  2480.                      input_filename, lineno);
  2481.           finish_stmt ();
  2482.         }
  2483.     /* This is the case with input operands as well.  */
  2484.     | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
  2485.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2486.           emit_line_note (input_filename, lineno);
  2487.           c_expand_asm_operands ($4, $6, $8, NULL_TREE,
  2488.                      $2 == ridpointers[(int)RID_VOLATILE],
  2489.                      input_filename, lineno);
  2490.           finish_stmt ();
  2491.         }
  2492.     /* This is the case with clobbered registers as well.  */
  2493.     | ASM maybe_type_qual '(' string ':' asm_operands ':'
  2494.         asm_operands ':' asm_clobbers ')' ';'
  2495.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2496.           emit_line_note (input_filename, lineno);
  2497.           c_expand_asm_operands ($4, $6, $8, $10,
  2498.                      $2 == ridpointers[(int)RID_VOLATILE],
  2499.                      input_filename, lineno);
  2500.           finish_stmt ();
  2501.         }
  2502.     | GOTO identifier ';'
  2503.         { tree decl;
  2504.           emit_line_note (input_filename, lineno);
  2505.           decl = lookup_label ($2);
  2506.           TREE_USED (decl) = 1;
  2507.           expand_goto (decl); }
  2508.     | IDENTIFIER ':'
  2509.         { tree label = define_label (input_filename, lineno, $1);
  2510.           emit_nop ();
  2511.           if (label)
  2512.             expand_label (label); }
  2513.       stmt
  2514.         { finish_stmt (); }
  2515.     | TYPENAME_COLON
  2516.         { tree label = define_label (input_filename, lineno, $1);
  2517.           if (label)
  2518.             expand_label (label); }
  2519.       stmt
  2520.         { finish_stmt (); }
  2521.     | ';'
  2522.         { finish_stmt (); }
  2523.  
  2524.     /* Exception handling extentions.  */
  2525.     | RAISE raise_identifier '(' exprlist ')' ';'
  2526.         { expand_cplus_raise ($2, $4, NULL_TREE);
  2527.           finish_stmt (); }
  2528.     | RAISE raise_identifier LEFT_RIGHT ';'
  2529.         { expand_cplus_raise ($2, NULL_TREE, NULL_TREE);
  2530.           finish_stmt (); }
  2531.     | try EXCEPT identifier '{'
  2532.         {
  2533.           tree decl = cplus_expand_end_try ($1);
  2534.           $<ttype>2 = current_exception_type;
  2535.           $<ttype>4 = current_exception_decl;
  2536.           $<ttype>$ = current_exception_object;
  2537.           cplus_expand_start_except ($3, decl);
  2538.           pushlevel (0);
  2539.           clear_last_expr ();
  2540.           push_momentary ();
  2541.           expand_start_bindings (0);
  2542.           stmt_decl_msg = 0;
  2543.         }
  2544.       except_stmts '}'
  2545.         {
  2546.           tree decls = getdecls ();
  2547.           /* If there is a default exception to handle,
  2548.              handle it here.  */
  2549.           if ($6)
  2550.             expand_expr ($6, 0, 0, 0);
  2551.           expand_end_bindings (decls, decls != 0, 1);
  2552.           poplevel (decls != 0, 1, 0);
  2553.           pop_momentary ();
  2554.           current_exception_type = $<ttype>2;
  2555.           current_exception_decl = $<ttype>4;
  2556.           current_exception_object = $<ttype>5;
  2557.           cplus_expand_end_except ($6);
  2558.         }
  2559.     | try RERAISE raise_identifiers /* ';' checked for at bottom.  */
  2560.         { tree name = get_identifier ("(compiler error)");
  2561.           tree orig_ex_type = current_exception_type;
  2562.           tree orig_ex_decl = current_exception_decl;
  2563.           tree orig_ex_obj = current_exception_object;
  2564.           tree decl = cplus_expand_end_try ($1), decls;
  2565.  
  2566.           /* Start hidden EXCEPT.  */
  2567.           cplus_expand_start_except (name, decl);
  2568.           pushlevel (0);
  2569.           clear_last_expr ();
  2570.           push_momentary ();
  2571.           expand_start_bindings (0);
  2572.           stmt_decl_msg = 0;
  2573.  
  2574.           /* This sets up the reraise.  */
  2575.           expand_cplus_reraise ($3);
  2576.  
  2577.           decls = getdecls ();
  2578.           expand_end_bindings (decls, decls != 0, 1);
  2579.           poplevel (decls != 0, 1, 0);
  2580.           pop_momentary ();
  2581.           current_exception_type = orig_ex_type;
  2582.           current_exception_decl = orig_ex_decl;
  2583.           current_exception_object = orig_ex_obj;
  2584.           /* This will reraise for us.  */
  2585.           cplus_expand_end_except (error_mark_node);
  2586.           if (yychar == YYEMPTY)
  2587.             yychar = YYLEX;
  2588.           if (yychar != ';')
  2589.             error ("missing ';' after reraise statement");
  2590.         }
  2591.     | try  %prec EMPTY
  2592.         { yyerror ("`except' missing after `try' statement");
  2593.           /* Terminate the binding contour started by special
  2594.              code in `.pushlevel'.  Automagically pops off
  2595.              the conditional we started for `try' stmt.  */
  2596.           cplus_expand_end_try ($1);
  2597.           expand_end_bindings (0, 0, 1);
  2598.           poplevel (0, 0, 0);
  2599.           pop_momentary ();
  2600.           YYERROR; }
  2601.     ;
  2602.  
  2603. try:      TRY '{' '}'
  2604.         { $$ = 0; }
  2605.     | try_head stmts '}'
  2606.         {
  2607.           $$ = 1;
  2608.           pop_implicit_try_blocks (NULL_TREE);
  2609.         }
  2610.     | try_head error '}'
  2611.         {
  2612.           $$ = 0;
  2613.           pop_implicit_try_blocks (NULL_TREE);
  2614.         }
  2615.     ;
  2616.  
  2617. try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel
  2618.  
  2619. except_stmts:
  2620.       /* empty */
  2621.         { $$ = NULL_TREE; }
  2622.     | except_stmts raise_identifier
  2623.         {
  2624.           tree type = lookup_exception_type (current_class_type, current_class_name, $2);
  2625.           if (type == NULL_TREE)
  2626.             {
  2627.               error ("`%s' is not an exception type",
  2628.                  IDENTIFIER_POINTER (TREE_VALUE ($2)));
  2629.               current_exception_type = NULL_TREE;
  2630.               TREE_TYPE (current_exception_object) = error_mark_node;
  2631.             }
  2632.           else
  2633.             {
  2634.               current_exception_type = type;
  2635.               /* In-place union.  */
  2636.               TREE_TYPE (current_exception_object) = type;
  2637.             }
  2638.           expand_cplus_start_catch ($2);
  2639.         }
  2640.       compstmt
  2641.         {
  2642.           expand_cplus_end_catch (0);
  2643.         }
  2644.     | except_stmts DEFAULT
  2645.         {
  2646.           if ($1)
  2647.             error ("duplicate default in exception handler");
  2648.           current_exception_type = NULL_TREE;
  2649.           /* Takes it right out of scope.  */
  2650.           TREE_TYPE (current_exception_object) = error_mark_node;
  2651.  
  2652.           if (! expand_catch_default ())
  2653.             compiler_error ("default catch botch");
  2654.  
  2655.           /* The default exception is handled as the
  2656.              last in the chain of exceptions handled.  */
  2657.           do_pending_stack_adjust ();
  2658.           start_sequence ();
  2659.           $1 = make_node (RTL_EXPR);
  2660.           TREE_TYPE ($1) = void_type_node;
  2661.         }
  2662.       compstmt
  2663.         {
  2664.           do_pending_stack_adjust ();
  2665.           if (! expand_catch (NULL_TREE))
  2666.             compiler_error ("except nesting botch");
  2667.           if (! expand_escape_except ())
  2668.             compiler_error ("except nesting botch");
  2669.           RTL_EXPR_SEQUENCE ($1) = (struct rtx_def *)get_insns ();
  2670.           end_sequence ();
  2671.         }
  2672.     ;
  2673.  
  2674. forhead.1:
  2675.       FOR '(' ';'
  2676.         { $$ = NULL_TREE; }
  2677.     | FOR '(' expr ';'
  2678.         { $$ = $3; }
  2679.     | FOR '(' '{' '}'
  2680.         { $$ = NULL_TREE; }
  2681.     ;
  2682.  
  2683. forhead.2:
  2684.       FOR '(' decl
  2685.         { $$ = 0; }
  2686.     | FOR '(' error ';'
  2687.         { $$ = 0; }
  2688.     | FOR '(' '{' .pushlevel stmts '}'
  2689.         { $$ = 1; }
  2690.     | FOR '(' '{' .pushlevel error '}'
  2691.         { $$ = -1; }
  2692.     ;
  2693.  
  2694. /* Either a type-qualifier or nothing.  First thing in an `asm' statement.  */
  2695.  
  2696. maybe_type_qual:
  2697.     /* empty */
  2698.         { if (pedantic)
  2699.             warning ("ANSI C forbids use of `asm' keyword");
  2700.           emit_line_note (input_filename, lineno); }
  2701.     | TYPE_QUAL
  2702.         { if (pedantic)
  2703.             warning ("ANSI C forbids use of `asm' keyword");
  2704.           emit_line_note (input_filename, lineno); }
  2705.     ;
  2706.  
  2707. xexpr:
  2708.     /* empty */
  2709.         { $$ = NULL_TREE; }
  2710.     | expr
  2711.     | error
  2712.         { $$ = NULL_TREE; }
  2713.     ;
  2714.  
  2715. /* These are the operands other than the first string and colon
  2716.    in  asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x))  */
  2717. asm_operands: /* empty */
  2718.         { $$ = NULL_TREE; }
  2719.     | nonnull_asm_operands
  2720.     ;
  2721.  
  2722. nonnull_asm_operands:
  2723.       asm_operand
  2724.     | nonnull_asm_operands ',' asm_operand
  2725.         { $$ = chainon ($1, $3); }
  2726.     ;
  2727.  
  2728. asm_operand:
  2729.       STRING '(' expr ')'
  2730.         { $$ = build_tree_list ($1, $3); }
  2731.     ;
  2732.  
  2733. asm_clobbers:
  2734.       STRING
  2735.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  2736.     | asm_clobbers ',' STRING
  2737.         { $$ = tree_cons (NULL_TREE, $3, $1); }
  2738.     ;
  2739.  
  2740. /* This is what appears inside the parens in a function declarator.
  2741.    Its value is represented in the format that grokdeclarator expects.
  2742.  
  2743.    In C++, declaring a function with no parameters
  2744.    means that that function takes *no* parameters.  */
  2745. parmlist:  /* empty */
  2746.         {
  2747.           if (strict_prototype)
  2748.             $$ = void_list_node;
  2749.           else
  2750.             $$ = NULL_TREE;
  2751.         }
  2752.     | parms
  2753.           {
  2754.           $$ = chainon ($1, void_list_node);
  2755.           TREE_PARMLIST ($$) = 1;
  2756.         }
  2757.     | parms ',' ELLIPSIS
  2758.         {
  2759.           $$ = $1;
  2760.           TREE_PARMLIST ($$) = 1;
  2761.         }
  2762.     /* C++ allows an ellipsis without a separating ',' */
  2763.     | parms ELLIPSIS
  2764.         {
  2765.           $$ = $1;
  2766.           TREE_PARMLIST ($$) = 1;
  2767.         }
  2768.     | ELLIPSIS
  2769.         {
  2770.           $$ = NULL_TREE;
  2771.         }
  2772.     | TYPENAME_ELLIPSIS
  2773.         {
  2774.           $$ = $1;
  2775.           TREE_PARMLIST ($$) = 1;
  2776.         }
  2777.     | parms TYPENAME_ELLIPSIS
  2778.         {
  2779.           $$ = $1;
  2780.           TREE_PARMLIST ($$) = 1;
  2781.         }
  2782.     | parms ':'
  2783.         {
  2784.           /* This helps us recover from really nasty
  2785.              parse errors, for example, a missing right
  2786.              parenthesis.  */
  2787.           yyerror ("possibly missing ')'");
  2788.           $$ = chainon ($1, void_list_node);
  2789.           TREE_PARMLIST ($$) = 1;
  2790.           yyungetc (':', 0);
  2791.           yychar = ')';
  2792.         }
  2793.     ;
  2794.  
  2795. /* A nonempty list of parameter declarations or type names.  */
  2796. parms:
  2797.       parm opt.init
  2798.         { $$ = build_tree_list ($2, $1); }
  2799.     | parms ',' parm opt.init
  2800.         { $$ = chainon ($1, build_tree_list ($4, $3)); }
  2801.     | parms ',' bad_parm opt.init
  2802.         { $$ = chainon ($1, build_tree_list ($4, $3)); }
  2803.     ;
  2804.  
  2805. /* A single parameter declaration or parameter type name,
  2806.    as found in a parmlist.  */
  2807. parm:
  2808.       typed_declspecs dont_see_typename notype_declarator
  2809.         { $$ = build_tree_list ($1, $3);
  2810.           see_typename (); }
  2811.     | typed_declspecs dont_see_typename absdcl
  2812.         { $$ = build_tree_list ($1, $3);
  2813.           see_typename (); }
  2814.     | declmods dont_see_typename notype_declarator
  2815.         { $$ = build_tree_list ($1, $3);
  2816.           see_typename (); }
  2817.     | declmods dont_see_typename absdcl
  2818.         { $$ = build_tree_list ($1, $3);
  2819.           see_typename (); }
  2820.     ;
  2821.  
  2822. see_typename: type_quals
  2823.     { see_typename (); }
  2824.     ;
  2825.  
  2826. dont_see_typename: /* empty */
  2827.     { dont_see_typename (); }
  2828.     ;
  2829.  
  2830. bad_parm:
  2831.       dummy_decl notype_declarator
  2832.         {
  2833.           warning ("type specifier omitted for parameter");
  2834.           $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $2);
  2835.         }
  2836.     | dummy_decl absdcl
  2837.         {
  2838.           warning ("type specifier omitted for parameter");
  2839.           $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $2);
  2840.         }
  2841.     ;
  2842.  
  2843.     /* C++ extension: allow for initialization */
  2844. opt.init:
  2845.       /* empty */
  2846.         { $$ = NULL_TREE; }
  2847.     | '=' init
  2848.         { $$ = $2; }
  2849.     ;
  2850.  
  2851. maybe_raises:
  2852.       /* empty */
  2853.         { $$ = NULL_TREE; }
  2854.     | RAISES raise_identifiers  %prec EMPTY
  2855.         { $$ = $2; }
  2856.     ;
  2857.  
  2858. raise_identifier:
  2859.       ALL
  2860.         { $$ = void_list_node; }
  2861.     | IDENTIFIER
  2862.         { $$ = build_decl_list (NULL_TREE, $1); }
  2863.     | TYPENAME
  2864.         { $$ = build_decl_list (NULL_TREE, $1); }
  2865.     | SCOPE IDENTIFIER
  2866.         { $$ = build_decl_list (void_type_node, $2); }
  2867.     | SCOPE TYPENAME
  2868.         { $$ = build_decl_list (void_type_node, $2); }
  2869.     | scoped_identifier IDENTIFIER
  2870.         { $$ = build_decl_list ($1, $2); }
  2871.     | scoped_identifier TYPENAME
  2872.         { $$ = build_decl_list ($1, $2); }
  2873.  
  2874. raise_identifiers:
  2875.       raise_identifier
  2876.     | raise_identifiers ',' raise_identifier
  2877.         {
  2878.             TREE_CHAIN ($3) = $1;
  2879.           $$ = $3;
  2880.         }
  2881.     ;
  2882.  
  2883. operator_name:
  2884.       OPERATOR '*'
  2885.         { $$ = build_opid (0, MULT_EXPR); }
  2886.     | OPERATOR '/'
  2887.         { $$ = build_opid (0, TRUNC_DIV_EXPR); }
  2888.     | OPERATOR '%'
  2889.         { $$ = build_opid (0, TRUNC_MOD_EXPR); }
  2890.     | OPERATOR '+'
  2891.         { $$ = build_opid (0, PLUS_EXPR); }
  2892.     | OPERATOR '-'
  2893.         { $$ = build_opid (0, MINUS_EXPR); }
  2894.     | OPERATOR '&'
  2895.         { $$ = build_opid (0, BIT_AND_EXPR); }
  2896.     | OPERATOR '|'
  2897.         { $$ = build_opid (0, BIT_IOR_EXPR); }
  2898.     | OPERATOR '^'
  2899.         { $$ = build_opid (0, BIT_XOR_EXPR); }
  2900.     | OPERATOR '~'
  2901.         { $$ = build_opid (0, BIT_NOT_EXPR); }
  2902.     | OPERATOR ARITHCOMPARE
  2903.         { $$ = build_opid (0, $2); }
  2904.     | OPERATOR EQCOMPARE
  2905.         { $$ = build_opid (0, $2); }
  2906.     | OPERATOR ASSIGN
  2907.         { $$ = build_opid (MODIFY_EXPR, $2); }
  2908.     | OPERATOR '='
  2909.         {
  2910.           $$ = build_opid (MODIFY_EXPR, NOP_EXPR);
  2911.           if (current_class_type)
  2912.             {
  2913.               TYPE_HAS_ASSIGNMENT (current_class_type) = 1;
  2914.               TYPE_GETS_ASSIGNMENT (current_class_type) = 1;
  2915.             }
  2916.         }
  2917.     | OPERATOR LSHIFT
  2918.         { $$ = build_opid (0, $2); }
  2919.     | OPERATOR RSHIFT
  2920.         { $$ = build_opid (0, $2); }
  2921.     | OPERATOR PLUSPLUS
  2922.         { $$ = build_opid (0, POSTINCREMENT_EXPR); }
  2923.     | OPERATOR MINUSMINUS
  2924.         { $$ = build_opid (0, PREDECREMENT_EXPR); }
  2925.     | OPERATOR ANDAND
  2926.         { $$ = build_opid (0, TRUTH_ANDIF_EXPR); }
  2927.     | OPERATOR OROR
  2928.         { $$ = build_opid (0, TRUTH_ORIF_EXPR); }
  2929.     | OPERATOR '!'
  2930.         { $$ = build_opid (0, TRUTH_NOT_EXPR); }
  2931.     | OPERATOR '?' ':'
  2932.         { $$ = build_opid (0, COND_EXPR); }
  2933.     | OPERATOR MIN_MAX
  2934.         { $$ = build_opid (0, $2); }
  2935.     | OPERATOR POINTSAT  %prec EMPTY
  2936.         { $$ = build_opid (0, COMPONENT_REF); }
  2937.     | OPERATOR POINTSAT_LEFT_RIGHT type_quals  %prec '.'
  2938.         {
  2939.           if (yychar == YYEMPTY)
  2940.             yychar = YYLEX;
  2941.           if (yychar == '(' || yychar == LEFT_RIGHT)
  2942.             {
  2943.               $$ = build_opid (0, METHOD_CALL_EXPR);
  2944.               if (current_class_type)
  2945.             {
  2946.               tree t = current_class_type;
  2947.               while (t)
  2948.                 {
  2949.                   TYPE_OVERLOADS_METHOD_CALL_EXPR (t) = 1;
  2950.                   t = TYPE_NEXT_VARIANT (t);
  2951.                 }
  2952.             }
  2953.             }
  2954.           else
  2955.             $$ = build_parse_node (CALL_EXPR, build_opid (0, COMPONENT_REF), void_list_node, $3);
  2956.         }
  2957.     | OPERATOR LEFT_RIGHT
  2958.         { $$ = build_opid (0, CALL_EXPR);
  2959.           if (current_class_type)
  2960.             {
  2961.               tree t = current_class_type;
  2962.               while (t)
  2963.             {
  2964.               TYPE_OVERLOADS_CALL_EXPR (t) = 1;
  2965.               t = TYPE_NEXT_VARIANT (t);
  2966.             }
  2967.             }
  2968.         }
  2969.     | OPERATOR '[' ']'
  2970.         { $$ = build_opid (0, ARRAY_REF);
  2971.           if (current_class_type)
  2972.             {
  2973.               tree t = current_class_type;
  2974.               while (t)
  2975.             {
  2976.               TYPE_OVERLOADS_ARRAY_REF (t) = 1;
  2977.               t = TYPE_NEXT_VARIANT (t);
  2978.             }
  2979.             }
  2980.         }
  2981.     | OPERATOR NEW
  2982.         {
  2983.           $$ = build_opid (0, NEW_EXPR);
  2984.           if (current_class_type)
  2985.             {
  2986.               tree t = current_class_type;
  2987.               while (t)
  2988.             {
  2989.               TREE_GETS_NEW (t) = 1;
  2990.               t = TYPE_NEXT_VARIANT (t);
  2991.             }
  2992.             }
  2993.         }
  2994.     | OPERATOR DELETE
  2995.         {
  2996.           $$ = build_opid (0, DELETE_EXPR);
  2997.           if (current_class_type)
  2998.             {
  2999.               tree t = current_class_type;
  3000.               while (t)
  3001.             {
  3002.               TREE_GETS_DELETE (t) = 1;
  3003.               t = TYPE_NEXT_VARIANT (t);
  3004.             }
  3005.             }
  3006.         }
  3007.  
  3008.     /* These should do `groktypename' and set up TREE_HAS_X_CONVERSION
  3009.        here, rather than doing it in class.c .  */
  3010.     | OPERATOR typed_typespecs absdcl
  3011.         {
  3012.           $$ = build1 (TYPE_EXPR, $2, $3);
  3013.         }
  3014.     | OPERATOR error
  3015.         { $$ = build_opid (ERROR_MARK, ERROR_MARK); }
  3016.     ;
  3017.  
  3018. %%
  3019.  
  3020. #if YYDEBUG != 0
  3021. db_yyerror (s, yyps, yychar)
  3022.      char *s;
  3023.      short *yyps;
  3024.      int yychar;
  3025. {
  3026.   FILE *yyout;
  3027.   char buf[1024];
  3028.   int st;
  3029.  
  3030.   yyerror (s);
  3031.   printf ("State is %d, input token number is %d.\n", *yyps, yychar);
  3032.  
  3033. #ifdef PARSE_OUTPUT
  3034.   if (*yyps < 1) fatal ("Cannot start from here");
  3035.   else if ((yyout = fopen (PARSE_OUTPUT, "r")) == NULL)
  3036.     error ("cannot open file %s", PARSE_OUTPUT);
  3037.   else
  3038.     {
  3039.       printf ("That is to say,\n\n");
  3040.       while (fgets(buf, sizeof (buf)-1, yyout))
  3041.     {
  3042.       if (buf[0] != 's') continue;
  3043.       st = atoi (buf+6);
  3044.       if (st != *yyps) continue;
  3045.       printf ("%s", buf);
  3046.       while (fgets (buf, sizeof (buf)-1, yyout))
  3047.         {
  3048.           if (buf[0] == 's') break;
  3049.           printf ("%s", buf);
  3050.         }
  3051.       break;
  3052.     }
  3053.       printf ("With the token %s\n", yytname[YYTRANSLATE (yychar)]);
  3054.       fclose (yyout);
  3055.     }
  3056. #endif
  3057. }
  3058. #endif
  3059.  
  3060. void
  3061. yyerror (string)
  3062.      char *string;
  3063. {
  3064.   extern FILE *finput;
  3065.   extern char *token_buffer;
  3066.   char buf[200];
  3067.  
  3068.   strcpy (buf, string);
  3069.  
  3070.   /* We can't print string and character constants well
  3071.      because the token_buffer contains the result of processing escapes.  */
  3072.   if (end_of_file || feof (finput))
  3073.     strcat (buf, " at end of input");
  3074.   else if (token_buffer[0] == 0)
  3075.     strcat (buf, " at null character");
  3076.   else if (token_buffer[0] == '"')
  3077.     strcat (buf, " before string constant");
  3078.   else if (token_buffer[0] == '\'')
  3079.     strcat (buf, " before character constant");
  3080.   else
  3081.     strcat (buf, " before `%s'");
  3082.  
  3083.   error (buf, token_buffer);
  3084. }
  3085.  
  3086. static int *reduce_count;
  3087. static int *token_count;
  3088.  
  3089. #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
  3090. #define TOKEN_LENGTH (256 + YYNTBASE + 1)
  3091.  
  3092. int *
  3093. init_parse ()
  3094. {
  3095. #ifdef GATHER_STATISTICS
  3096.   reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
  3097.   bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
  3098.   reduce_count += 1;
  3099.   token_count = (int *)malloc (sizeof (int) * TOKEN_LENGTH);
  3100.   bzero (token_count, sizeof (int) * TOKEN_LENGTH);
  3101. #endif
  3102.   return token_count;
  3103. }
  3104.  
  3105. #ifdef GATHER_STATISTICS
  3106. void
  3107. yyhook (yyn)
  3108.      int yyn;
  3109. {
  3110.   reduce_count[yyn] += 1;
  3111. }
  3112. #endif
  3113.  
  3114. static int reduce_cmp (p, q)
  3115.      int *p, *q;
  3116. {
  3117.   return reduce_count[*q] - reduce_count[*p];
  3118. }
  3119.  
  3120. static int token_cmp (p, q)
  3121.      int *p, *q;
  3122. {
  3123.   return token_count[*q] - token_count[*p];
  3124. }
  3125.  
  3126. void
  3127. print_parse_statistics ()
  3128. {
  3129.   int i;
  3130.   int maxlen = REDUCE_LENGTH;
  3131.   unsigned *sorted;
  3132.   
  3133.   if (reduce_count[-1] == 0)
  3134.     return;
  3135.  
  3136.   if (TOKEN_LENGTH > REDUCE_LENGTH)
  3137.     maxlen = TOKEN_LENGTH;
  3138.   sorted = (unsigned *) alloca (sizeof (int) * maxlen);
  3139.  
  3140.   for (i = 0; i < TOKEN_LENGTH; i++)
  3141.     sorted[i] = i;
  3142.   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
  3143.   for (i = 0; i < TOKEN_LENGTH; i++)
  3144.     {
  3145.       int index = sorted[i];
  3146.       if (token_count[index] == 0)
  3147.     break;
  3148.       if (token_count[index] < token_count[-1])
  3149.     break;
  3150.       fprintf (stderr, "token %d", index);
  3151. #if YYDEBUG
  3152.       fprintf (stderr, ", `%s'", yytname[YYTRANSLATE (index)]);
  3153. #endif
  3154.       fprintf (stderr, ", count = %d\n", token_count[index]);
  3155.     }
  3156.   fprintf (stderr, "\n");
  3157.   for (i = 0; i < REDUCE_LENGTH; i++)
  3158.     sorted[i] = i;
  3159.   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
  3160.   for (i = 0; i < REDUCE_LENGTH; i++)
  3161.     {
  3162.       int index = sorted[i];
  3163.       if (reduce_count[index] == 0)
  3164.     break;
  3165.       if (reduce_count[index] < reduce_count[-1])
  3166.     break;
  3167.       fprintf (stderr, "rule %d", index);
  3168. #if YYDEBUG
  3169.       fprintf (stderr, ", line %d", yyrline[index]);
  3170. #endif
  3171.       fprintf (stderr, ", count = %d\n", reduce_count[index]);
  3172.     }
  3173.   fprintf (stderr, "\n");
  3174. }
  3175.